diff --git a/go.mod b/go.mod index 4e92b8a9..bc0ae5f3 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/SovereignCloudStack/cluster-stack-operator v0.1.0-alpha.7 github.com/gophercloud/gophercloud/v2 v2.1.0 github.com/gophercloud/utils/v2 v2.0.0-20240812072210-8ce1fc0f2894 - github.com/onsi/ginkgo/v2 v2.20.1 + github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/stretchr/testify v1.9.0 k8s.io/api v0.30.3 @@ -16,7 +16,7 @@ require ( k8s.io/client-go v0.30.3 k8s.io/klog/v2 v2.130.1 sigs.k8s.io/cluster-api v1.8.1 - sigs.k8s.io/cluster-api-provider-openstack v0.9.2 + sigs.k8s.io/cluster-api-provider-openstack v0.10.5 sigs.k8s.io/controller-runtime v0.18.5 sigs.k8s.io/yaml v1.4.0 ) @@ -51,7 +51,6 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gophercloud/gophercloud v1.11.0 // indirect github.com/imdario/mergo v0.3.15 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -90,6 +89,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.30.3 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kubernetes v1.28.3 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect oras.land/oras-go/v2 v2.5.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/go.sum b/go.sum index c5fd83e9..638afb87 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,6 @@ github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSF github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gophercloud/gophercloud v1.11.0 h1:ls0O747DIq1D8SUHc7r2vI8BFbMLeLFuENaAIfEx7OM= -github.com/gophercloud/gophercloud v1.11.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gophercloud/gophercloud/v2 v2.1.0 h1:91p6c+uMckXyx39nSIYjDirDBnPVFQq0q1njLNPX+NY= github.com/gophercloud/gophercloud/v2 v2.1.0/go.mod h1:f2hMRC7Kakbv5vM7wSGHrIPZh6JZR60GVHryJlF/K44= github.com/gophercloud/utils/v2 v2.0.0-20240812072210-8ce1fc0f2894 h1:KgYK/Mf71IdN7+sq2cVmY8Jtumi26GxahN7nlV0ETBQ= @@ -132,8 +130,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= -github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -202,7 +200,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= @@ -216,7 +213,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= @@ -230,7 +226,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= @@ -240,7 +235,6 @@ golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -295,6 +289,8 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubernetes v1.28.3 h1:XTci6gzk+JR51UZuZQCFJ4CsyUkfivSjLI4O1P9z6LY= +k8s.io/kubernetes v1.28.3/go.mod h1:NhAysZWvHtNcJFFHic87ofxQN7loylCQwg3ZvXVDbag= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= @@ -303,8 +299,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0 h1:Tc9rS7JJoZ9sl sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.0/go.mod h1:1ewhL9l1gkPcU/IU/6rFYfikf+7Y5imWv7ARVbBOzNs= sigs.k8s.io/cluster-api v1.8.1 h1:OA3w1CjCmXXXDL7aY3WDe+seL0mdFVJX1K5mZwqKbDE= sigs.k8s.io/cluster-api v1.8.1/go.mod h1:pXv5LqLxuIbhGIXykyNKiJh+KrLweSBajVHHitPLyoY= -sigs.k8s.io/cluster-api-provider-openstack v0.9.2 h1:TGFtclX81HFiCkRJQe0wnWsnT/FBB69gSPFwcxQ+qlM= -sigs.k8s.io/cluster-api-provider-openstack v0.9.2/go.mod h1:ecR9lx4XbOr3Gg2CGNgM3wguuV6l31Nd5rUccE+xjKs= +sigs.k8s.io/cluster-api-provider-openstack v0.10.5 h1:oLaLnX+SzdT0xsP3Inq8+usM4tvhy/J9qVmEC7rjZVQ= +sigs.k8s.io/cluster-api-provider-openstack v0.10.5/go.mod h1:/3VAIzFoAxX77QykzyE6tnHD9aC8lYiQVKbfKPoX20w= sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk= sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/vendor/github.com/gophercloud/gophercloud/.gitignore b/vendor/github.com/gophercloud/gophercloud/.gitignore deleted file mode 100644 index d7a5e529..00000000 --- a/vendor/github.com/gophercloud/gophercloud/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -**/*.swp -.idea -.vscode -testing_*.coverprofile diff --git a/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md b/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md deleted file mode 100644 index 0eec3e6d..00000000 --- a/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md +++ /dev/null @@ -1,930 +0,0 @@ -## v1.11.0 (2024-03-07) - -This version reverts the inclusion of Context in the v1 branch. This inclusion -didn't add much value because no packages were using it; on the other hand, it -introduced a bug when using the Context property of the Provider client. - -## v1.10.0 (2024-02-27) **RETRACTED**: see https://github.com/gophercloud/gophercloud/issues/2969 - -* [GH-2893](https://github.com/gophercloud/gophercloud/pull/2893) [v1] authentication: Add WithContext functions -* [GH-2894](https://github.com/gophercloud/gophercloud/pull/2894) [v1] pager: Add WithContext functions -* [GH-2899](https://github.com/gophercloud/gophercloud/pull/2899) [v1] Authenticate with a clouds.yaml -* [GH-2917](https://github.com/gophercloud/gophercloud/pull/2917) [v1] Add ParseOption type to made clouds.Parse() more usable for optional With* funcs -* [GH-2924](https://github.com/gophercloud/gophercloud/pull/2924) [v1] build(deps): bump EmilienM/devstack-action from 0.11 to 0.14 -* [GH-2933](https://github.com/gophercloud/gophercloud/pull/2933) [v1] Fix AllowReauth reauthentication -* [GH-2950](https://github.com/gophercloud/gophercloud/pull/2950) [v1] compute: Use volumeID, not attachmentID for volume attachments - -## v1.9.0 (2024-02-02) **RETRACTED**: see https://github.com/gophercloud/gophercloud/issues/2969 - -New features and improvements: - -* [GH-2884](https://github.com/gophercloud/gophercloud/pull/2884) [v1] Context-aware methods to ProviderClient and ServiceClient -* [GH-2887](https://github.com/gophercloud/gophercloud/pull/2887) [v1] Add support of Flavors and FlavorProfiles for Octavia -* [GH-2875](https://github.com/gophercloud/gophercloud/pull/2875) [v1] [db/v1/instance]: adding support for availability_zone for a db instance - -CI changes: - -* [GH-2856](https://github.com/gophercloud/gophercloud/pull/2856) [v1] Fix devstack install on EOL magnum branches -* [GH-2857](https://github.com/gophercloud/gophercloud/pull/2857) [v1] Fix networking acceptance tests -* [GH-2858](https://github.com/gophercloud/gophercloud/pull/2858) [v1] build(deps): bump actions/upload-artifact from 3 to 4 -* [GH-2859](https://github.com/gophercloud/gophercloud/pull/2859) [v1] build(deps): bump github/codeql-action from 2 to 3 - -## v1.8.0 (2023-11-30) - -New features and improvements: - -* [GH-2800](https://github.com/gophercloud/gophercloud/pull/2800) [v1] Fix options initialization in ServiceClient.Request (fixes #2798) -* [GH-2823](https://github.com/gophercloud/gophercloud/pull/2823) [v1] Add more godoc to GuestFormat -* [GH-2826](https://github.com/gophercloud/gophercloud/pull/2826) Allow objects.CreateTempURL with names containing /v1/ - -CI changes: - -* [GH-2802](https://github.com/gophercloud/gophercloud/pull/2802) [v1] Add job for bobcat stable/2023.2 -* [GH-2819](https://github.com/gophercloud/gophercloud/pull/2819) [v1] Test files alongside code -* [GH-2814](https://github.com/gophercloud/gophercloud/pull/2814) Make fixtures part of tests -* [GH-2796](https://github.com/gophercloud/gophercloud/pull/2796) [v1] ci/unit: switch to coverallsapp/github-action -* [GH-2840](https://github.com/gophercloud/gophercloud/pull/2840) unit tests: Fix the installation of tools - -## v1.7.0 (2023-09-22) - -New features and improvements: - -* [GH-2782](https://github.com/gophercloud/gophercloud/pull/2782) [v1] (manual clean backport) Add tag field to compute block_device_v2 - -CI changes: - -* [GH-2760](https://github.com/gophercloud/gophercloud/pull/2760) [v1 backports] semver auto labels -* [GH-2775](https://github.com/gophercloud/gophercloud/pull/2775) [v1] Fix typos in comments -* [GH-2783](https://github.com/gophercloud/gophercloud/pull/2783) [v1] (clean manual backport) ci/functional: fix ubuntu version & add antelope -* [GH-2785](https://github.com/gophercloud/gophercloud/pull/2785) [v1] Acceptance: Handle numerical version names in version comparison helpers -* [GH-2787](https://github.com/gophercloud/gophercloud/pull/2787) backport-v1: fixes to semver label -* [GH-2788](https://github.com/gophercloud/gophercloud/pull/2788) [v1] Make acceptance tests internal - - -## v1.6.0 (2023-08-30) - -New features and improvements: - -* [GH-2712](https://github.com/gophercloud/gophercloud/pull/2712) [v1] README: minor change to test backport workflow -* [GH-2713](https://github.com/gophercloud/gophercloud/pull/2713) [v1] tests: run MultiAttach with a capable Cinder Type -* [GH-2714](https://github.com/gophercloud/gophercloud/pull/2714) [v1] Add CRUD support for encryption in volume v3 types -* [GH-2715](https://github.com/gophercloud/gophercloud/pull/2715) [v1] Add projectID to fwaas_v2 policy CreateOpts and ListOpts -* [GH-2716](https://github.com/gophercloud/gophercloud/pull/2716) [v1] Add projectID to fwaas_v2 CreateOpts -* [GH-2717](https://github.com/gophercloud/gophercloud/pull/2717) [v1] [manila]: add reset and force delete actions to a snapshot -* [GH-2718](https://github.com/gophercloud/gophercloud/pull/2718) [v1] [cinder]: add reset and force delete actions to volumes and snapshots -* [GH-2721](https://github.com/gophercloud/gophercloud/pull/2721) [v1] orchestration: Explicit error in optionsmap creation -* [GH-2723](https://github.com/gophercloud/gophercloud/pull/2723) [v1] Add conductor API to Baremetal V1 -* [GH-2729](https://github.com/gophercloud/gophercloud/pull/2729) [v1] networking/v2/ports: allow list filter by security group - -CI changes: - -* [GH-2675](https://github.com/gophercloud/gophercloud/pull/2675) [v1][CI] Drop periodic jobs from stable branch -* [GH-2683](https://github.com/gophercloud/gophercloud/pull/2683) [v1] CI tweaks - - -## v1.5.0 (2023-06-21) - -New features and improvements: - -* [GH-2634](https://github.com/gophercloud/gophercloud/pull/2634) baremetal: update inspection inventory with recent additions -* [GH-2635](https://github.com/gophercloud/gophercloud/pull/2635) [manila]: Add Share Replicas support -* [GH-2637](https://github.com/gophercloud/gophercloud/pull/2637) [FWaaS_v2]: Add FWaaS_V2 workflow and enable tests -* [GH-2639](https://github.com/gophercloud/gophercloud/pull/2639) Implement errors.Unwrap() on unexpected status code errors -* [GH-2648](https://github.com/gophercloud/gophercloud/pull/2648) [manila]: implement share transfer API - - -## v1.4.0 (2023-05-25) - -New features and improvements: - -* [GH-2465](https://github.com/gophercloud/gophercloud/pull/2465) keystone: add v3 limits update operation -* [GH-2596](https://github.com/gophercloud/gophercloud/pull/2596) keystone: add v3 limits get operation -* [GH-2618](https://github.com/gophercloud/gophercloud/pull/2618) keystone: add v3 limits delete operation -* [GH-2616](https://github.com/gophercloud/gophercloud/pull/2616) Add CRUD support for register limit APIs -* [GH-2610](https://github.com/gophercloud/gophercloud/pull/2610) Add PUT/HEAD/DELETE for identity/v3/OS-INHERIT -* [GH-2597](https://github.com/gophercloud/gophercloud/pull/2597) Add validation and optimise objects.BulkDelete -* [GH-2602](https://github.com/gophercloud/gophercloud/pull/2602) [swift v1]: introduce a TempURLKey argument for objects.CreateTempURLOpts struct -* [GH-2623](https://github.com/gophercloud/gophercloud/pull/2623) Add the ability to remove ingress/egress policies from fwaas_v2 groups -* [GH-2625](https://github.com/gophercloud/gophercloud/pull/2625) neutron: Support trunk_details extension - -CI changes: - -* [GH-2608](https://github.com/gophercloud/gophercloud/pull/2608) Drop train and ussuri jobs -* [GH-2589](https://github.com/gophercloud/gophercloud/pull/2589) Bump EmilienM/devstack-action from 0.10 to 0.11 -* [GH-2604](https://github.com/gophercloud/gophercloud/pull/2604) Bump mheap/github-action-required-labels from 3 to 4 -* [GH-2620](https://github.com/gophercloud/gophercloud/pull/2620) Pin goimport dep to a version that works with go 1.14 -* [GH-2619](https://github.com/gophercloud/gophercloud/pull/2619) Fix version comparison for acceptance tests -* [GH-2627](https://github.com/gophercloud/gophercloud/pull/2627) Limits: Fix ToDo to create registered limit and use it -* [GH-2629](https://github.com/gophercloud/gophercloud/pull/2629) [manila]: Add share from snapshot restore functional test - - -## v1.3.0 (2023-03-28) - -* [GH-2464](https://github.com/gophercloud/gophercloud/pull/2464) keystone: add v3 limits create operation -* [GH-2512](https://github.com/gophercloud/gophercloud/pull/2512) Manila: add List for share-access-rules API -* [GH-2529](https://github.com/gophercloud/gophercloud/pull/2529) Added target state "rebuild" for Ironic nodes -* [GH-2539](https://github.com/gophercloud/gophercloud/pull/2539) Add release instructions -* [GH-2540](https://github.com/gophercloud/gophercloud/pull/2540) [all] IsEmpty to check for HTTP status 204 -* [GH-2543](https://github.com/gophercloud/gophercloud/pull/2543) keystone: add v3 OS-FEDERATION mappings get operation -* [GH-2545](https://github.com/gophercloud/gophercloud/pull/2545) baremetal: add inspection_{started,finished}_at to Node -* [GH-2546](https://github.com/gophercloud/gophercloud/pull/2546) Drop train job for baremetal -* [GH-2549](https://github.com/gophercloud/gophercloud/pull/2549) objects: Clarify ExtractContent usage -* [GH-2550](https://github.com/gophercloud/gophercloud/pull/2550) keystone: add v3 OS-FEDERATION mappings update operation -* [GH-2552](https://github.com/gophercloud/gophercloud/pull/2552) objectstorage: Reject container names with a slash -* [GH-2555](https://github.com/gophercloud/gophercloud/pull/2555) nova: introduce servers.ListSimple along with the more detailed servers.List -* [GH-2558](https://github.com/gophercloud/gophercloud/pull/2558) Expand docs on 'clientconfig' usage -* [GH-2563](https://github.com/gophercloud/gophercloud/pull/2563) Support propagate_uplink_status for Ports -* [GH-2567](https://github.com/gophercloud/gophercloud/pull/2567) Fix invalid baremetal-introspection service type -* [GH-2568](https://github.com/gophercloud/gophercloud/pull/2568) Prefer github mirrors over opendev repos -* [GH-2571](https://github.com/gophercloud/gophercloud/pull/2571) Swift V1: support object versioning -* [GH-2572](https://github.com/gophercloud/gophercloud/pull/2572) networking v2: add extraroutes Add and Remove methods -* [GH-2573](https://github.com/gophercloud/gophercloud/pull/2573) Enable tests for object versioning -* [GH-2576](https://github.com/gophercloud/gophercloud/pull/2576) keystone: add v3 OS-FEDERATION mappings delete operation -* [GH-2578](https://github.com/gophercloud/gophercloud/pull/2578) Add periodic jobs for OpenStack zed release and reduce periodic jobs frequency -* [GH-2580](https://github.com/gophercloud/gophercloud/pull/2580) [neutron v2]: Add support for network segments update -* [GH-2583](https://github.com/gophercloud/gophercloud/pull/2583) Add missing rule protocol constants for IPIP -* [GH-2584](https://github.com/gophercloud/gophercloud/pull/2584) CI: workaround mongodb dependency for messaging and clustering master jobs -* [GH-2587](https://github.com/gophercloud/gophercloud/pull/2587) fix: Incorrect Documentation -* [GH-2593](https://github.com/gophercloud/gophercloud/pull/2593) Make TestMTUNetworkCRUDL deterministic -* [GH-2594](https://github.com/gophercloud/gophercloud/pull/2594) Bump actions/setup-go from 3 to 4 - - -## v1.2.0 (2023-01-27) - -Starting with this version, Gophercloud sends its actual version in the -user-agent string in the format `gophercloud/v1.2.0`. It no longer sends the -hardcoded string `gophercloud/2.0.0`. - -* [GH-2542](https://github.com/gophercloud/gophercloud/pull/2542) Add field hidden in containerinfra/v1/clustertemplates -* [GH-2537](https://github.com/gophercloud/gophercloud/pull/2537) Support value_specs for Ports -* [GH-2530](https://github.com/gophercloud/gophercloud/pull/2530) keystone: add v3 OS-FEDERATION mappings create operation -* [GH-2519](https://github.com/gophercloud/gophercloud/pull/2519) Modify user-agent header to ensure current gophercloud version is provided - -## v1.1.1 (2022-12-07) - -The GOPROXY cache for v1.1.0 was corrupted with a tag pointing to the wrong commit. This release fixes the problem by exposing a new release with the same content. - -Please use `v1.1.1` instead of `v1.1.0` to avoid cache issues. - -## v1.1.0 (2022-11-24) - -* [GH-2513](https://github.com/gophercloud/gophercloud/pull/2513) objectstorage: Do not parse NoContent responses -* [GH-2503](https://github.com/gophercloud/gophercloud/pull/2503) Bump golang.org/x/crypto -* [GH-2501](https://github.com/gophercloud/gophercloud/pull/2501) Staskraev/l3 agent scheduler -* [GH-2496](https://github.com/gophercloud/gophercloud/pull/2496) Manila: add Get for share-access-rules API -* [GH-2491](https://github.com/gophercloud/gophercloud/pull/2491) Add VipQosPolicyID to loadbalancer Create and Update -* [GH-2488](https://github.com/gophercloud/gophercloud/pull/2488) Add Persistance for octavia pools.UpdateOpts -* [GH-2487](https://github.com/gophercloud/gophercloud/pull/2487) Add Prometheus protocol for octavia listeners -* [GH-2482](https://github.com/gophercloud/gophercloud/pull/2482) Add createdAt, updatedAt and provisionUpdatedAt fields in Baremetal V1 nodes -* [GH-2479](https://github.com/gophercloud/gophercloud/pull/2479) Add service_types support for neutron subnet -* [GH-2477](https://github.com/gophercloud/gophercloud/pull/2477) Port CreatedAt and UpdatedAt: add back JSON tags -* [GH-2475](https://github.com/gophercloud/gophercloud/pull/2475) Support old time format for port CreatedAt and UpdatedAt -* [GH-2474](https://github.com/gophercloud/gophercloud/pull/2474) Implementing re-image volumeaction -* [GH-2470](https://github.com/gophercloud/gophercloud/pull/2470) keystone: add v3 limits GetEnforcementModel operation -* [GH-2468](https://github.com/gophercloud/gophercloud/pull/2468) keystone: add v3 OS-FEDERATION extension List Mappings -* [GH-2458](https://github.com/gophercloud/gophercloud/pull/2458) Fix typo in blockstorage/v3/attachments docs -* [GH-2456](https://github.com/gophercloud/gophercloud/pull/2456) Add support for Update for flavors -* [GH-2453](https://github.com/gophercloud/gophercloud/pull/2453) Add description to flavor -* [GH-2417](https://github.com/gophercloud/gophercloud/pull/2417) Neutron v2: ScheduleBGPSpeakerOpts, RemoveBGPSpeaker, Lis… - -## 1.0.0 (2022-08-29) - -UPGRADE NOTES + PROMISE OF COMPATIBILITY - -* Introducing Gophercloud v1! Like for every other release so far, all clients will upgrade automatically with `go get -d github.com/gophercloud/gophercloud` unless the dependency is pinned in `go.mod`. -* Gophercloud v1 comes with a promise of compatibility: no breaking changes are expected to merge before v2.0.0. - -IMPROVEMENTS - -* Added `compute.v2/extensions/services.Delete` [GH-2427](https://github.com/gophercloud/gophercloud/pull/2427) -* Added support for `standard-attr-revisions` to `networking/v2/networks`, `networking/v2/ports`, and `networking/v2/subnets` [GH-2437](https://github.com/gophercloud/gophercloud/pull/2437) -* Added `updated_at` and `created_at` fields to `networking/v2/ports.Port` [GH-2445](https://github.com/gophercloud/gophercloud/pull/2445) - -## 0.25.0 (May 30, 2022) - -BREAKING CHANGES - -* Replaced `blockstorage/noauth.NewBlockStorageNoAuth` with `NewBlockStorageNoAuthV2` and `NewBlockStorageNoAuthV3` [GH-2343](https://github.com/gophercloud/gophercloud/pull/2343) -* Renamed `blockstorage/extensions/schedulerstats.Capabilities`'s `GoodnessFuction` field to `GoodnessFunction` [GH-2346](https://github.com/gophercloud/gophercloud/pull/2346) - -IMPROVEMENTS - -* Added `RequestOpts.OmitHeaders` to provider client [GH-2315](https://github.com/gophercloud/gophercloud/pull/2315) -* Added `identity/v3/extensions/projectendpoints.List` [GH-2304](https://github.com/gophercloud/gophercloud/pull/2304) -* Added `identity/v3/extensions/projectendpoints.Create` [GH-2304](https://github.com/gophercloud/gophercloud/pull/2304) -* Added `identity/v3/extensions/projectendpoints.Delete` [GH-2304](https://github.com/gophercloud/gophercloud/pull/2304) -* Added protocol `any` to `networking/v2/extensions/security/rules.Create` [GH-2310](https://github.com/gophercloud/gophercloud/pull/2310) -* Added `REDIRECT_PREFIX` and `REDIRECT_HTTP_CODE` to `loadbalancer/v2/l7policies.Create` [GH-2324](https://github.com/gophercloud/gophercloud/pull/2324) -* Added `SOURCE_IP_PORT` LB method to `loadbalancer/v2/pools.Create` [GH-2300](https://github.com/gophercloud/gophercloud/pull/2300) -* Added `AllocatedCapacityGB` capability to `blockstorage/extensions/schedulerstats.Capabilities` [GH-2348](https://github.com/gophercloud/gophercloud/pull/2348) -* Added `Metadata` to `dns/v2/recordset.RecordSet` [GH-2353](https://github.com/gophercloud/gophercloud/pull/2353) -* Added missing fields to `compute/v2/extensions/servergroups.List` [GH-2355](https://github.com/gophercloud/gophercloud/pull/2355) -* Added missing labels fields to `containerinfra/v1/nodegroups` [GH-2377](https://github.com/gophercloud/gophercloud/pull/2377) -* Added missing fields to `loadbalancer/v2/listeners.Listener` [GH-2407](https://github.com/gophercloud/gophercloud/pull/2407) -* Added `identity/v3/limits.List` [GH-2360](https://github.com/gophercloud/gophercloud/pull/2360) -* Added `ParentProviderUUID` to `placement/v1/resourceproviders.Create` [GH-2356](https://github.com/gophercloud/gophercloud/pull/2356) -* Added `placement/v1/resourceproviders.Delete` [GH-2357](https://github.com/gophercloud/gophercloud/pull/2357) -* Added `placement/v1/resourceproviders.Get` [GH-2358](https://github.com/gophercloud/gophercloud/pull/2358) -* Added `placement/v1/resourceproviders.Update` [GH-2359](https://github.com/gophercloud/gophercloud/pull/2359) -* Added `networking/v2/extensions/bgp/peers.List` [GH-2241](https://github.com/gophercloud/gophercloud/pull/2241) -* Added `networking/v2/extensions/bgp/peers.Get` [GH-2241](https://github.com/gophercloud/gophercloud/pull/2241) -* Added `networking/v2/extensions/bgp/peers.Create` [GH-2388](https://github.com/gophercloud/gophercloud/pull/2388) -* Added `networking/v2/extensions/bgp/peers.Delete` [GH-2388](https://github.com/gophercloud/gophercloud/pull/2388) -* Added `networking/v2/extensions/bgp/peers.Update` [GH-2396](https://github.com/gophercloud/gophercloud/pull/2396) -* Added `networking/v2/extensions/bgp/speakers.Create` [GH-2395](https://github.com/gophercloud/gophercloud/pull/2395) -* Added `networking/v2/extensions/bgp/speakers.Delete` [GH-2395](https://github.com/gophercloud/gophercloud/pull/2395) -* Added `networking/v2/extensions/bgp/speakers.Update` [GH-2400](https://github.com/gophercloud/gophercloud/pull/2400) -* Added `networking/v2/extensions/bgp/speakers.AddBGPPeer` [GH-2400](https://github.com/gophercloud/gophercloud/pull/2400) -* Added `networking/v2/extensions/bgp/speakers.RemoveBGPPeer` [GH-2400](https://github.com/gophercloud/gophercloud/pull/2400) -* Added `networking/v2/extensions/bgp/speakers.GetAdvertisedRoutes` [GH-2406](https://github.com/gophercloud/gophercloud/pull/2406) -* Added `networking/v2/extensions/bgp/speakers.AddGatewayNetwork` [GH-2406](https://github.com/gophercloud/gophercloud/pull/2406) -* Added `networking/v2/extensions/bgp/speakers.RemoveGatewayNetwork` [GH-2406](https://github.com/gophercloud/gophercloud/pull/2406) -* Added `baremetal/v1/nodes.SetMaintenance` and `baremetal/v1/nodes.UnsetMaintenance` [GH-2384](https://github.com/gophercloud/gophercloud/pull/2384) -* Added `sharedfilesystems/v2/services.List` [GH-2350](https://github.com/gophercloud/gophercloud/pull/2350) -* Added `sharedfilesystems/v2/schedulerstats.List` [GH-2350](https://github.com/gophercloud/gophercloud/pull/2350) -* Added `sharedfilesystems/v2/schedulerstats.ListDetail` [GH-2350](https://github.com/gophercloud/gophercloud/pull/2350) -* Added ability to handle 502 and 504 errors [GH-2245](https://github.com/gophercloud/gophercloud/pull/2245) -* Added `IncludeSubtree` to `identity/v3/roles.ListAssignments` [GH-2411](https://github.com/gophercloud/gophercloud/pull/2411) - -## 0.24.0 (December 13, 2021) - -UPGRADE NOTES - -* Set Go minimum version to 1.14 [GH-2294](https://github.com/gophercloud/gophercloud/pull/2294) - -IMPROVEMENTS - -* Added `blockstorage/v3/qos.Get` [GH-2283](https://github.com/gophercloud/gophercloud/pull/2283) -* Added `blockstorage/v3/qos.Update` [GH-2283](https://github.com/gophercloud/gophercloud/pull/2283) -* Added `blockstorage/v3/qos.DeleteKeys` [GH-2283](https://github.com/gophercloud/gophercloud/pull/2283) -* Added `blockstorage/v3/qos.Associate` [GH-2284](https://github.com/gophercloud/gophercloud/pull/2284) -* Added `blockstorage/v3/qos.Disassociate` [GH-2284](https://github.com/gophercloud/gophercloud/pull/2284) -* Added `blockstorage/v3/qos.DisassociateAll` [GH-2284](https://github.com/gophercloud/gophercloud/pull/2284) -* Added `blockstorage/v3/qos.ListAssociations` [GH-2284](https://github.com/gophercloud/gophercloud/pull/2284) - -## 0.23.0 (November 12, 2021) - -IMPROVEMENTS - -* Added `networking/v2/extensions/agents.ListBGPSpeakers` [GH-2229](https://github.com/gophercloud/gophercloud/pull/2229) -* Added `networking/v2/extensions/bgp/speakers.BGPSpeaker` [GH-2229](https://github.com/gophercloud/gophercloud/pull/2229) -* Added `identity/v3/roles.Project.Domain` [GH-2235](https://github.com/gophercloud/gophercloud/pull/2235) -* Added `identity/v3/roles.User.Domain` [GH-2235](https://github.com/gophercloud/gophercloud/pull/2235) -* Added `identity/v3/roles.Group.Domain` [GH-2235](https://github.com/gophercloud/gophercloud/pull/2235) -* Added `loadbalancer/v2/pools.CreateOpts.Tags` [GH-2237](https://github.com/gophercloud/gophercloud/pull/2237) -* Added `loadbalancer/v2/pools.UpdateOpts.Tags` [GH-2237](https://github.com/gophercloud/gophercloud/pull/2237) -* Added `loadbalancer/v2/pools.Pool.Tags` [GH-2237](https://github.com/gophercloud/gophercloud/pull/2237) -* Added `networking/v2/extensions/bgp/speakers.List` [GH-2238](https://github.com/gophercloud/gophercloud/pull/2238) -* Added `networking/v2/extensions/bgp/speakers.Get` [GH-2238](https://github.com/gophercloud/gophercloud/pull/2238) -* Added `compute/v2/extensions/keypairs.CreateOpts.Type` [GH-2231](https://github.com/gophercloud/gophercloud/pull/2231) -* When doing Keystone re-authentification, keep the error if it failed [GH-2259](https://github.com/gophercloud/gophercloud/pull/2259) -* Added new loadbalancer pool monitor types (TLS-HELLO, UDP-CONNECT and SCTP) [GH-2237](https://github.com/gophercloud/gophercloud/pull/2261) - -## 0.22.0 (October 7, 2021) - -BREAKING CHANGES - -* The types of several Object Storage Update fields have been changed to pointers in order to allow the value to be unset via the HTTP headers: - * `objectstorage/v1/accounts.UpdateOpts.ContentType` - * `objectstorage/v1/accounts.UpdateOpts.DetectContentType` - * `objectstorage/v1/containers.UpdateOpts.ContainerRead` - * `objectstorage/v1/containers.UpdateOpts.ContainerSyncTo` - * `objectstorage/v1/containers.UpdateOpts.ContainerSyncKey` - * `objectstorage/v1/containers.UpdateOpts.ContainerWrite` - * `objectstorage/v1/containers.UpdateOpts.ContentType` - * `objectstorage/v1/containers.UpdateOpts.DetectContentType` - * `objectstorage/v1/objects.UpdateOpts.ContentDisposition` - * `objectstorage/v1/objects.UpdateOpts.ContentEncoding` - * `objectstorage/v1/objects.UpdateOpts.ContentType` - * `objectstorage/v1/objects.UpdateOpts.DeleteAfter` - * `objectstorage/v1/objects.UpdateOpts.DeleteAt` - * `objectstorage/v1/objects.UpdateOpts.DetectContentType` - -BUG FIXES - -* Fixed issue with not being able to unset Object Storage values via HTTP headers [GH-2218](https://github.com/gophercloud/gophercloud/pull/2218) - -IMPROVEMENTS - -* Added `compute/v2/servers.Server.ServerGroups` [GH-2217](https://github.com/gophercloud/gophercloud/pull/2217) -* Added `imageservice/v2/images.ReplaceImageProtected` to allow the `protected` field to be updated [GH-2221](https://github.com/gophercloud/gophercloud/pull/2221) -* More details added to the 404/Not Found error message [GH-2223](https://github.com/gophercloud/gophercloud/pull/2223) -* Added `openstack/baremetal/v1/nodes.CreateSubscriptionOpts.HttpHeaders` [GH-2224](https://github.com/gophercloud/gophercloud/pull/2224) - -## 0.21.0 (September 14, 2021) - -IMPROVEMENTS - -* Added `blockstorage/extensions/volumehost` [GH-2212](https://github.com/gophercloud/gophercloud/pull/2212) -* Added `loadbalancer/v2/listeners.CreateOpts.Tags` [GH-2214](https://github.com/gophercloud/gophercloud/pull/2214) -* Added `loadbalancer/v2/listeners.UpdateOpts.Tags` [GH-2214](https://github.com/gophercloud/gophercloud/pull/2214) -* Added `loadbalancer/v2/listeners.Listener.Tags` [GH-2214](https://github.com/gophercloud/gophercloud/pull/2214) - -## 0.20.0 (August 10, 2021) - -IMPROVEMENTS - -* Added `RetryFunc` to enable custom retry functions. [GH-2194](https://github.com/gophercloud/gophercloud/pull/2194) -* Added `openstack/baremetal/v1/nodes.GetVendorPassthruMethods` [GH-2201](https://github.com/gophercloud/gophercloud/pull/2201) -* Added `openstack/baremetal/v1/nodes.GetAllSubscriptions` [GH-2201](https://github.com/gophercloud/gophercloud/pull/2201) -* Added `openstack/baremetal/v1/nodes.GetSubscription` [GH-2201](https://github.com/gophercloud/gophercloud/pull/2201) -* Added `openstack/baremetal/v1/nodes.DeleteSubscription` [GH-2201](https://github.com/gophercloud/gophercloud/pull/2201) -* Added `openstack/baremetal/v1/nodes.CreateSubscription` [GH-2201](https://github.com/gophercloud/gophercloud/pull/2201) - -## 0.19.0 (July 22, 2021) - -NOTES / BREAKING CHANGES - -* `compute/v2/extensions/keypairs.List` now takes a `ListOptsBuilder` argument [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* `compute/v2/extensions/keypairs.Get` now takes a `GetOptsBuilder` argument [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* `compute/v2/extensions/keypairs.Delete` now takes a `DeleteOptsBuilder` argument [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* `compute/v2/extensions/hypervisors.List` now takes a `ListOptsBuilder` argument [GH-2187](https://github.com/gophercloud/gophercloud/pull/2187) - -IMPROVEMENTS - -* Added `blockstorage/v3/qos.List` [GH-2167](https://github.com/gophercloud/gophercloud/pull/2167) -* Added `compute/v2/extensions/volumeattach.CreateOpts.Tag` [GH-2177](https://github.com/gophercloud/gophercloud/pull/2177) -* Added `compute/v2/extensions/volumeattach.CreateOpts.DeleteOnTermination` [GH-2177](https://github.com/gophercloud/gophercloud/pull/2177) -* Added `compute/v2/extensions/volumeattach.VolumeAttachment.Tag` [GH-2177](https://github.com/gophercloud/gophercloud/pull/2177) -* Added `compute/v2/extensions/volumeattach.VolumeAttachment.DeleteOnTermination` [GH-2177](https://github.com/gophercloud/gophercloud/pull/2177) -* Added `db/v1/instances.Instance.Address` [GH-2179](https://github.com/gophercloud/gophercloud/pull/2179) -* Added `compute/v2/servers.ListOpts.AvailabilityZone` [GH-2098](https://github.com/gophercloud/gophercloud/pull/2098) -* Added `compute/v2/extensions/keypairs.ListOpts` [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* Added `compute/v2/extensions/keypairs.GetOpts` [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* Added `compute/v2/extensions/keypairs.DeleteOpts` [GH-2186](https://github.com/gophercloud/gophercloud/pull/2186) -* Added `objectstorage/v2/containers.GetHeader.Timestamp` [GH-2185](https://github.com/gophercloud/gophercloud/pull/2185) -* Added `compute/v2/extensions.ListOpts` [GH-2187](https://github.com/gophercloud/gophercloud/pull/2187) -* Added `sharedfilesystems/v2/shares.Share.CreateShareFromSnapshotSupport` [GH-2191](https://github.com/gophercloud/gophercloud/pull/2191) -* Added `compute/v2/servers.Network.Tag` for use in `CreateOpts` [GH-2193](https://github.com/gophercloud/gophercloud/pull/2193) - -## 0.18.0 (June 11, 2021) - -NOTES / BREAKING CHANGES - -* As of [GH-2160](https://github.com/gophercloud/gophercloud/pull/2160), Gophercloud no longer URL encodes Object Storage containers and object names. You can still encode them yourself before passing the names to the Object Storage functions. - -* `baremetal/v1/nodes.ListBIOSSettings` now takes three parameters. The third, new, parameter is `ListBIOSSettingsOptsBuilder` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) - -BUG FIXES - -* Fixed expected OK codes to use default codes [GH-2173](https://github.com/gophercloud/gophercloud/pull/2173) -* Fixed inablity to create sub-containers (objects with `/` in their name) [GH-2160](https://github.com/gophercloud/gophercloud/pull/2160) - -IMPROVEMENTS - -* Added `orchestration/v1/stacks.ListOpts.ShowHidden` [GH-2104](https://github.com/gophercloud/gophercloud/pull/2104) -* Added `loadbalancer/v2/listeners.ProtocolSCTP` [GH-2149](https://github.com/gophercloud/gophercloud/pull/2149) -* Added `loadbalancer/v2/listeners.CreateOpts.TLSVersions` [GH-2150](https://github.com/gophercloud/gophercloud/pull/2150) -* Added `loadbalancer/v2/listeners.UpdateOpts.TLSVersions` [GH-2150](https://github.com/gophercloud/gophercloud/pull/2150) -* Added `baremetal/v1/nodes.CreateOpts.NetworkData` [GH-2154](https://github.com/gophercloud/gophercloud/pull/2154) -* Added `baremetal/v1/nodes.Node.NetworkData` [GH-2154](https://github.com/gophercloud/gophercloud/pull/2154) -* Added `loadbalancer/v2/pools.ProtocolPROXYV2` [GH-2158](https://github.com/gophercloud/gophercloud/pull/2158) -* Added `loadbalancer/v2/pools.ProtocolSCTP` [GH-2158](https://github.com/gophercloud/gophercloud/pull/2158) -* Added `placement/v1/resourceproviders.GetAllocations` [GH-2162](https://github.com/gophercloud/gophercloud/pull/2162) -* Added `baremetal/v1/nodes.CreateOpts.BIOSInterface` [GH-2164](https://github.com/gophercloud/gophercloud/pull/2164) -* Added `baremetal/v1/nodes.Node.BIOSInterface` [GH-2164](https://github.com/gophercloud/gophercloud/pull/2164) -* Added `baremetal/v1/nodes.NodeValidation.BIOS` [GH-2164](https://github.com/gophercloud/gophercloud/pull/2164) -* Added `baremetal/v1/nodes.ListBIOSSettings` [GH-2171](https://github.com/gophercloud/gophercloud/pull/2171) -* Added `baremetal/v1/nodes.GetBIOSSetting` [GH-2171](https://github.com/gophercloud/gophercloud/pull/2171) -* Added `baremetal/v1/nodes.ListBIOSSettingsOpts` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.AttributeType` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.AllowableValues` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.LowerBound` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.UpperBound` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.MinLength` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.MaxLength` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.ReadOnly` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.ResetRequired` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) -* Added `baremetal/v1/nodes.BIOSSetting.Unique` [GH-2174](https://github.com/gophercloud/gophercloud/pull/2174) - -## 0.17.0 (April 9, 2021) - -IMPROVEMENTS - -* `networking/v2/extensions/quotas.QuotaDetail.Reserved` can handle both `int` and `string` values [GH-2126](https://github.com/gophercloud/gophercloud/pull/2126) -* Added `blockstorage/v3/volumetypes.ListExtraSpecs` [GH-2123](https://github.com/gophercloud/gophercloud/pull/2123) -* Added `blockstorage/v3/volumetypes.GetExtraSpec` [GH-2123](https://github.com/gophercloud/gophercloud/pull/2123) -* Added `blockstorage/v3/volumetypes.CreateExtraSpecs` [GH-2123](https://github.com/gophercloud/gophercloud/pull/2123) -* Added `blockstorage/v3/volumetypes.UpdateExtraSpec` [GH-2123](https://github.com/gophercloud/gophercloud/pull/2123) -* Added `blockstorage/v3/volumetypes.DeleteExtraSpec` [GH-2123](https://github.com/gophercloud/gophercloud/pull/2123) -* Added `identity/v3/roles.ListAssignmentOpts.IncludeNames` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `identity/v3/roles.AssignedRoles.Name` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `identity/v3/roles.Domain.Name` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `identity/v3/roles.Project.Name` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `identity/v3/roles.User.Name` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `identity/v3/roles.Group.Name` [GH-2133](https://github.com/gophercloud/gophercloud/pull/2133) -* Added `blockstorage/extensions/availabilityzones.List` [GH-2135](https://github.com/gophercloud/gophercloud/pull/2135) -* Added `blockstorage/v3/volumetypes.ListAccesses` [GH-2138](https://github.com/gophercloud/gophercloud/pull/2138) -* Added `blockstorage/v3/volumetypes.AddAccess` [GH-2138](https://github.com/gophercloud/gophercloud/pull/2138) -* Added `blockstorage/v3/volumetypes.RemoveAccess` [GH-2138](https://github.com/gophercloud/gophercloud/pull/2138) -* Added `blockstorage/v3/qos.Create` [GH-2140](https://github.com/gophercloud/gophercloud/pull/2140) -* Added `blockstorage/v3/qos.Delete` [GH-2140](https://github.com/gophercloud/gophercloud/pull/2140) - -## 0.16.0 (February 23, 2021) - -UPGRADE NOTES - -* `baremetal/v1/nodes.CleanStep.Interface` has changed from `string` to `StepInterface` [GH-2120](https://github.com/gophercloud/gophercloud/pull/2120) - -BUG FIXES - -* Fixed `xor` logic issues in `loadbalancers/v2/l7policies.CreateOpts` [GH-2087](https://github.com/gophercloud/gophercloud/pull/2087) -* Fixed `xor` logic issues in `loadbalancers/v2/listeners.CreateOpts` [GH-2087](https://github.com/gophercloud/gophercloud/pull/2087) -* Fixed `If-Modified-Since` so it's correctly sent in a `objectstorage/v1/objects.Download` request [GH-2108](https://github.com/gophercloud/gophercloud/pull/2108) -* Fixed `If-Unmodified-Since` so it's correctly sent in a `objectstorage/v1/objects.Download` request [GH-2108](https://github.com/gophercloud/gophercloud/pull/2108) - -IMPROVEMENTS - -* Added `blockstorage/extensions/limits.Get` [GH-2084](https://github.com/gophercloud/gophercloud/pull/2084) -* `clustering/v1/clusters.RemoveNodes` now returns an `ActionResult` [GH-2089](https://github.com/gophercloud/gophercloud/pull/2089) -* Added `identity/v3/projects.ListAvailable` [GH-2090](https://github.com/gophercloud/gophercloud/pull/2090) -* Added `blockstorage/extensions/backups.ListDetail` [GH-2085](https://github.com/gophercloud/gophercloud/pull/2085) -* Allow all ports to be removed in `networking/v2/extensions/fwaas_v2/groups.UpdateOpts` [GH-2073] -* Added `imageservice/v2/images.ListOpts.Hidden` [GH-2094](https://github.com/gophercloud/gophercloud/pull/2094) -* Added `imageservice/v2/images.CreateOpts.Hidden` [GH-2094](https://github.com/gophercloud/gophercloud/pull/2094) -* Added `imageservice/v2/images.ReplaceImageHidden` [GH-2094](https://github.com/gophercloud/gophercloud/pull/2094) -* Added `imageservice/v2/images.Image.Hidden` [GH-2094](https://github.com/gophercloud/gophercloud/pull/2094) -* Added `containerinfra/v1/clusters.CreateOpts.MasterLBEnabled` [GH-2102](https://github.com/gophercloud/gophercloud/pull/2102) -* Added the ability to define a custom function to handle "Retry-After" (429) responses [GH-2097](https://github.com/gophercloud/gophercloud/pull/2097) -* Added `baremetal/v1/nodes.JBOD` constant for the `RAIDLevel` type [GH-2103](https://github.com/gophercloud/gophercloud/pull/2103) -* Added support for Block Storage quotas of volume typed resources [GH-2109](https://github.com/gophercloud/gophercloud/pull/2109) -* Added `blockstorage/extensions/volumeactions.ChangeType` [GH-2113](https://github.com/gophercloud/gophercloud/pull/2113) -* Added `baremetal/v1/nodes.DeployStep` [GH-2120](https://github.com/gophercloud/gophercloud/pull/2120) -* Added `baremetal/v1/nodes.ProvisionStateOpts.DeploySteps` [GH-2120](https://github.com/gophercloud/gophercloud/pull/2120) -* Added `baremetal/v1/nodes.CreateOpts.AutomatedClean` [GH-2122](https://github.com/gophercloud/gophercloud/pull/2122) - -## 0.15.0 (December 27, 2020) - -BREAKING CHANGES - -* `compute/v2/extensions/servergroups.List` now takes a `ListOpts` parameter. You can pass `nil` if you don't need to use this. - -IMPROVEMENTS - -* Added `loadbalancer/v2/pools.CreateMemberOpts.Tags` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.UpdateMemberOpts.Backup` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.UpdateMemberOpts.MonitorAddress` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.UpdateMemberOpts.MonitorPort` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.UpdateMemberOpts.Tags` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.BatchUpdateMemberOpts.Backup` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.BatchUpdateMemberOpts.MonitorAddress` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.BatchUpdateMemberOpts.MonitorPort` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `loadbalancer/v2/pools.BatchUpdateMemberOpts.Tags` [GH-2056](https://github.com/gophercloud/gophercloud/pull/2056) -* Added `networking/v2/extensions/quotas.GetDetail` [GH-2061](https://github.com/gophercloud/gophercloud/pull/2061) -* Added `networking/v2/extensions/quotas.UpdateOpts.Trunk` [GH-2061](https://github.com/gophercloud/gophercloud/pull/2061) -* Added `objectstorage/v1/accounts.UpdateOpts.RemoveMetadata` [GH-2063](https://github.com/gophercloud/gophercloud/pull/2063) -* Added `objectstorage/v1/objects.UpdateOpts.RemoveMetadata` [GH-2063](https://github.com/gophercloud/gophercloud/pull/2063) -* Added `identity/v3/catalog.List` [GH-2067](https://github.com/gophercloud/gophercloud/pull/2067) -* Added `networking/v2/extensions/fwaas_v2/policies.List` [GH-2057](https://github.com/gophercloud/gophercloud/pull/2057) -* Added `networking/v2/extensions/fwaas_v2/policies.Create` [GH-2057](https://github.com/gophercloud/gophercloud/pull/2057) -* Added `networking/v2/extensions/fwaas_v2/policies.Get` [GH-2057](https://github.com/gophercloud/gophercloud/pull/2057) -* Added `networking/v2/extensions/fwaas_v2/policies.Update` [GH-2057](https://github.com/gophercloud/gophercloud/pull/2057) -* Added `networking/v2/extensions/fwaas_v2/policies.Delete` [GH-2057](https://github.com/gophercloud/gophercloud/pull/2057) -* Added `compute/v2/extensions/servergroups.ListOpts.AllProjects` [GH-2070](https://github.com/gophercloud/gophercloud/pull/2070) -* Added `objectstorage/v1/containers.CreateOpts.StoragePolicy` [GH-2075](https://github.com/gophercloud/gophercloud/pull/2075) -* Added `blockstorage/v3/snapshots.Update` [GH-2081](https://github.com/gophercloud/gophercloud/pull/2081) -* Added `loadbalancer/v2/l7policies.CreateOpts.Rules` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/listeners.CreateOpts.DefaultPool` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/listeners.CreateOpts.L7Policies` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/listeners.Listener.DefaultPool` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/loadbalancers.CreateOpts.Listeners` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/loadbalancers.CreateOpts.Pools` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/pools.CreateOpts.Members` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) -* Added `loadbalancer/v2/pools.CreateOpts.Monitor` [GH-2077](https://github.com/gophercloud/gophercloud/pull/2077) - - -## 0.14.0 (November 11, 2020) - -IMPROVEMENTS - -* Added `identity/v3/endpoints.Endpoint.Enabled` [GH-2030](https://github.com/gophercloud/gophercloud/pull/2030) -* Added `containerinfra/v1/clusters.Upgrade` [GH-2032](https://github.com/gophercloud/gophercloud/pull/2032) -* Added `compute/apiversions.List` [GH-2037](https://github.com/gophercloud/gophercloud/pull/2037) -* Added `compute/apiversions.Get` [GH-2037](https://github.com/gophercloud/gophercloud/pull/2037) -* Added `compute/v2/servers.ListOpts.IP` [GH-2038](https://github.com/gophercloud/gophercloud/pull/2038) -* Added `compute/v2/servers.ListOpts.IP6` [GH-2038](https://github.com/gophercloud/gophercloud/pull/2038) -* Added `compute/v2/servers.ListOpts.UserID` [GH-2038](https://github.com/gophercloud/gophercloud/pull/2038) -* Added `dns/v2/transfer/accept.List` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/accept.Get` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/accept.Create` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/requests.List` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/requests.Get` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/requests.Update` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `dns/v2/transfer/requests.Delete` [GH-2041](https://github.com/gophercloud/gophercloud/pull/2041) -* Added `baremetal/v1/nodes.RescueWait` [GH-2052](https://github.com/gophercloud/gophercloud/pull/2052) -* Added `baremetal/v1/nodes.Unrescuing` [GH-2052](https://github.com/gophercloud/gophercloud/pull/2052) -* Added `networking/v2/extensions/fwaas_v2/groups.List` [GH-2050](https://github.com/gophercloud/gophercloud/pull/2050) -* Added `networking/v2/extensions/fwaas_v2/groups.Get` [GH-2050](https://github.com/gophercloud/gophercloud/pull/2050) -* Added `networking/v2/extensions/fwaas_v2/groups.Create` [GH-2050](https://github.com/gophercloud/gophercloud/pull/2050) -* Added `networking/v2/extensions/fwaas_v2/groups.Update` [GH-2050](https://github.com/gophercloud/gophercloud/pull/2050) -* Added `networking/v2/extensions/fwaas_v2/groups.Delete` [GH-2050](https://github.com/gophercloud/gophercloud/pull/2050) - -BUG FIXES - -* Changed `networking/v2/extensions/layer3/routers.Routes` from `[]Route` to `*[]Route` [GH-2043](https://github.com/gophercloud/gophercloud/pull/2043) - -## 0.13.0 (September 27, 2020) - -IMPROVEMENTS - -* Added `ProtocolTerminatedHTTPS` as a valid listener protocol to `loadbalancer/v2/listeners` [GH-1992](https://github.com/gophercloud/gophercloud/pull/1992) -* Added `objectstorage/v1/objects.CreateTempURLOpts.Timestamp` [GH-1994](https://github.com/gophercloud/gophercloud/pull/1994) -* Added `compute/v2/extensions/schedulerhints.SchedulerHints.DifferentCell` [GH-2012](https://github.com/gophercloud/gophercloud/pull/2012) -* Added `loadbalancer/v2/quotas.Get` [GH-2010](https://github.com/gophercloud/gophercloud/pull/2010) -* Added `messaging/v2/queues.CreateOpts.EnableEncryptMessages` [GH-2016](https://github.com/gophercloud/gophercloud/pull/2016) -* Added `messaging/v2/queues.ListOpts.Name` [GH-2018](https://github.com/gophercloud/gophercloud/pull/2018) -* Added `messaging/v2/queues.ListOpts.WithCount` [GH-2018](https://github.com/gophercloud/gophercloud/pull/2018) -* Added `loadbalancer/v2/quotas.Update` [GH-2023](https://github.com/gophercloud/gophercloud/pull/2023) -* Added `loadbalancer/v2/loadbalancers.ListOpts.AvailabilityZone` [GH-2026](https://github.com/gophercloud/gophercloud/pull/2026) -* Added `loadbalancer/v2/loadbalancers.CreateOpts.AvailabilityZone` [GH-2026](https://github.com/gophercloud/gophercloud/pull/2026) -* Added `loadbalancer/v2/loadbalancers.LoadBalancer.AvailabilityZone` [GH-2026](https://github.com/gophercloud/gophercloud/pull/2026) -* Added `networking/v2/extensions/layer3/routers.ListL3Agents` [GH-2025](https://github.com/gophercloud/gophercloud/pull/2025) - -BUG FIXES - -* Fixed URL escaping in `objectstorage/v1/objects.CreateTempURL` [GH-1994](https://github.com/gophercloud/gophercloud/pull/1994) -* Remove unused `ServiceClient` from `compute/v2/servers.CreateOpts` [GH-2004](https://github.com/gophercloud/gophercloud/pull/2004) -* Changed `objectstorage/v1/objects.CreateOpts.DeleteAfter` from `int` to `int64` [GH-2014](https://github.com/gophercloud/gophercloud/pull/2014) -* Changed `objectstorage/v1/objects.CreateOpts.DeleteAt` from `int` to `int64` [GH-2014](https://github.com/gophercloud/gophercloud/pull/2014) -* Changed `objectstorage/v1/objects.UpdateOpts.DeleteAfter` from `int` to `int64` [GH-2014](https://github.com/gophercloud/gophercloud/pull/2014) -* Changed `objectstorage/v1/objects.UpdateOpts.DeleteAt` from `int` to `int64` [GH-2014](https://github.com/gophercloud/gophercloud/pull/2014) - - -## 0.12.0 (June 25, 2020) - -UPGRADE NOTES - -* The URL used in the `compute/v2/extensions/bootfromvolume` package has been changed from `os-volumes_boot` to `servers`. - -IMPROVEMENTS - -* The URL used in the `compute/v2/extensions/bootfromvolume` package has been changed from `os-volumes_boot` to `servers` [GH-1973](https://github.com/gophercloud/gophercloud/pull/1973) -* Modify `baremetal/v1/nodes.LogicalDisk.PhysicalDisks` type to support physical disks hints [GH-1982](https://github.com/gophercloud/gophercloud/pull/1982) -* Added `baremetalintrospection/httpbasic` which provides an HTTP Basic Auth client [GH-1986](https://github.com/gophercloud/gophercloud/pull/1986) -* Added `baremetal/httpbasic` which provides an HTTP Basic Auth client [GH-1983](https://github.com/gophercloud/gophercloud/pull/1983) -* Added `containerinfra/v1/clusters.CreateOpts.MergeLabels` [GH-1985](https://github.com/gophercloud/gophercloud/pull/1985) - -BUG FIXES - -* Changed `containerinfra/v1/clusters.Cluster.HealthStatusReason` from `string` to `map[string]interface{}` [GH-1968](https://github.com/gophercloud/gophercloud/pull/1968) -* Fixed marshalling of `blockstorage/extensions/backups.ImportBackup.Metadata` [GH-1967](https://github.com/gophercloud/gophercloud/pull/1967) -* Fixed typo of "OAUth" to "OAuth" in `identity/v3/extensions/oauth1` [GH-1969](https://github.com/gophercloud/gophercloud/pull/1969) -* Fixed goroutine leak during reauthentication [GH-1978](https://github.com/gophercloud/gophercloud/pull/1978) -* Changed `baremetalintrospection/v1/introspection.RootDiskType.Size` from `int` to `int64` [GH-1988](https://github.com/gophercloud/gophercloud/pull/1988) - -## 0.11.0 (May 14, 2020) - -UPGRADE NOTES - -* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930) -* All responses now have access to the returned headers. Please report any issues this has caused [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942) -* Changes have been made to the internal HTTP client to ensure response bodies are handled in a way that enables connections to be re-used more efficiently [GH-1952](https://github.com/gophercloud/gophercloud/pull/1952) - -IMPROVEMENTS - -* Added `objectstorage/v1/containers.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930) -* Added `objectstorage/v1/objects.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930) -* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930) -* All responses now have access to the returned headers [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942) -* Added `compute/v2/extensions/injectnetworkinfo.InjectNetworkInfo` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941) -* Added `compute/v2/extensions/resetnetwork.ResetNetwork` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941) -* Added `identity/v3/extensions/trusts.ListRoles` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939) -* Added `identity/v3/extensions/trusts.GetRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939) -* Added `identity/v3/extensions/trusts.CheckRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939) -* Added `identity/v3/extensions/oauth1.Create` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.CreateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.DeleteConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.ListConsumers` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.GetConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.UpdateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.RequestToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.AuthorizeToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.CreateAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.GetAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.RevokeAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.ListAccessTokens` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.ListAccessTokenRoles` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `identity/v3/extensions/oauth1.GetAccessTokenRole` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935) -* Added `networking/v2/extensions/agents.Update` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954) -* Added `networking/v2/extensions/agents.Delete` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954) -* Added `networking/v2/extensions/agents.ScheduleDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954) -* Added `networking/v2/extensions/agents.RemoveDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954) -* Added `identity/v3/projects.CreateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `identity/v3/projects.CreateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `identity/v3/projects.UpdateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `identity/v3/projects.UpdateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `identity/v3/projects.Project.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `identity/v3/projects.Options.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951) -* Added `imageservice/v2/images.Image.OpenStackImageImportMethods` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962) -* Added `imageservice/v2/images.Image.OpenStackImageStoreIDs` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962) - -BUG FIXES - -* Changed`identity/v3/extensions/trusts.Trust.RemainingUses` from `bool` to `int` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939) -* Changed `identity/v3/applicationcredentials.CreateOpts.ExpiresAt` from `string` to `*time.Time` [GH-1937](https://github.com/gophercloud/gophercloud/pull/1937) -* Fixed issue with unmarshalling/decoding slices of composed structs [GH-1964](https://github.com/gophercloud/gophercloud/pull/1964) - -## 0.10.0 (April 12, 2020) - -UPGRADE NOTES - -* The various `IDFromName` convenience functions have been moved to https://github.com/gophercloud/utils [GH-1897](https://github.com/gophercloud/gophercloud/pull/1897) -* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932) - -IMPROVEMENTS - -* Added `blockstorage/extensions/volumeactions.SetBootable` [GH-1891](https://github.com/gophercloud/gophercloud/pull/1891) -* Added `blockstorage/extensions/backups.Export` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894) -* Added `blockstorage/extensions/backups.Import` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894) -* Added `placement/v1/resourceproviders.GetTraits` [GH-1899](https://github.com/gophercloud/gophercloud/pull/1899) -* Added the ability to authenticate with Amazon EC2 Credentials [GH-1900](https://github.com/gophercloud/gophercloud/pull/1900) -* Added ability to list Nova services by binary and host [GH-1904](https://github.com/gophercloud/gophercloud/pull/1904) -* Added `compute/v2/extensions/services.Update` [GH-1902](https://github.com/gophercloud/gophercloud/pull/1902) -* Added system scope to v3 authentication [GH-1908](https://github.com/gophercloud/gophercloud/pull/1908) -* Added `identity/v3/extensions/ec2tokens.ValidateS3Token` [GH-1906](https://github.com/gophercloud/gophercloud/pull/1906) -* Added `containerinfra/v1/clusters.Cluster.HealthStatus` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910) -* Added `containerinfra/v1/clusters.Cluster.HealthStatusReason` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910) -* Added `loadbalancer/v2/amphorae.Failover` [GH-1912](https://github.com/gophercloud/gophercloud/pull/1912) -* Added `identity/v3/extensions/ec2credentials.List` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916) -* Added `identity/v3/extensions/ec2credentials.Get` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916) -* Added `identity/v3/extensions/ec2credentials.Create` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916) -* Added `identity/v3/extensions/ec2credentials.Delete` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916) -* Added `ErrUnexpectedResponseCode.ResponseHeader` [GH-1919](https://github.com/gophercloud/gophercloud/pull/1919) -* Added support for TOTP authentication [GH-1922](https://github.com/gophercloud/gophercloud/pull/1922) -* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932) -* Added `sharedfilesystems/v2/shares.GetExportLocation` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932) -* Added `sharedfilesystems/v2/shares.Revert` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931) -* Added `sharedfilesystems/v2/shares.ResetStatus` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931) -* Added `sharedfilesystems/v2/shares.ForceDelete` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931) -* Added `sharedfilesystems/v2/shares.Unmanage` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931) -* Added `blockstorage/v3/attachments.Create` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) -* Added `blockstorage/v3/attachments.List` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) -* Added `blockstorage/v3/attachments.Get` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) -* Added `blockstorage/v3/attachments.Update` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) -* Added `blockstorage/v3/attachments.Delete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) -* Added `blockstorage/v3/attachments.Complete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934) - -BUG FIXES - -* Fixed issue with Orchestration `get_file` only being able to read JSON and YAML files [GH-1915](https://github.com/gophercloud/gophercloud/pull/1915) - -## 0.9.0 (March 10, 2020) - -UPGRADE NOTES - -* The way we implement new API result fields added by microversions has changed. Previously, we would declare a dedicated `ExtractFoo` function in a file called `microversions.go`. Now, we are declaring those fields inline of the original result struct as a pointer. [GH-1854](https://github.com/gophercloud/gophercloud/pull/1854) - -* `compute/v2/servers.CreateOpts.Networks` has changed from `[]Network` to `interface{}` in order to support creating servers that have no networks. [GH-1884](https://github.com/gophercloud/gophercloud/pull/1884) - -IMPROVEMENTS - -* Added `compute/v2/extensions/instanceactions.List` [GH-1848](https://github.com/gophercloud/gophercloud/pull/1848) -* Added `compute/v2/extensions/instanceactions.Get` [GH-1848](https://github.com/gophercloud/gophercloud/pull/1848) -* Added `networking/v2/ports.List.FixedIPs` [GH-1849](https://github.com/gophercloud/gophercloud/pull/1849) -* Added `identity/v3/extensions/trusts.List` [GH-1855](https://github.com/gophercloud/gophercloud/pull/1855) -* Added `identity/v3/extensions/trusts.Get` [GH-1855](https://github.com/gophercloud/gophercloud/pull/1855) -* Added `identity/v3/extensions/trusts.Trust.ExpiresAt` [GH-1857](https://github.com/gophercloud/gophercloud/pull/1857) -* Added `identity/v3/extensions/trusts.Trust.DeletedAt` [GH-1857](https://github.com/gophercloud/gophercloud/pull/1857) -* Added `compute/v2/extensions/instanceactions.InstanceActionDetail` [GH-1851](https://github.com/gophercloud/gophercloud/pull/1851) -* Added `compute/v2/extensions/instanceactions.Event` [GH-1851](https://github.com/gophercloud/gophercloud/pull/1851) -* Added `compute/v2/extensions/instanceactions.ListOpts` [GH-1858](https://github.com/gophercloud/gophercloud/pull/1858) -* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey` [GH-1864](https://github.com/gophercloud/gophercloud/pull/1864) -* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey2` [GH-1864](https://github.com/gophercloud/gophercloud/pull/1864) -* Added `placement/v1/resourceproviders.GetUsages` [GH-1862](https://github.com/gophercloud/gophercloud/pull/1862) -* Added `placement/v1/resourceproviders.GetInventories` [GH-1862](https://github.com/gophercloud/gophercloud/pull/1862) -* Added `imageservice/v2/images.ReplaceImageMinRam` [GH-1867](https://github.com/gophercloud/gophercloud/pull/1867) -* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey` [GH-1865](https://github.com/gophercloud/gophercloud/pull/1865) -* Added `objectstorage/v1/containers.CreateOpts.TempURLKey2` [GH-1865](https://github.com/gophercloud/gophercloud/pull/1865) -* Added `blockstorage/extensions/volumetransfers.List` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869) -* Added `blockstorage/extensions/volumetransfers.Create` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869) -* Added `blockstorage/extensions/volumetransfers.Accept` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869) -* Added `blockstorage/extensions/volumetransfers.Get` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869) -* Added `blockstorage/extensions/volumetransfers.Delete` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869) -* Added `blockstorage/extensions/backups.RestoreFromBackup` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871) -* Added `blockstorage/v3/volumes.CreateOpts.BackupID` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871) -* Added `blockstorage/v3/volumes.Volume.BackupID` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871) -* Added `identity/v3/projects.ListOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.ListOpts.TagsAny` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.ListOpts.NotTags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.ListOpts.NotTagsAny` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.CreateOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.UpdateOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Added `identity/v3/projects.Project.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882) -* Changed `compute/v2/servers.CreateOpts.Networks` from `[]Network` to `interface{}` to support creating servers with no networks. [GH-1884](https://github.com/gophercloud/gophercloud/pull/1884) - - -BUG FIXES - -* Added support for `int64` headers, which were previously being silently dropped [GH-1860](https://github.com/gophercloud/gophercloud/pull/1860) -* Allow image properties with empty values [GH-1875](https://github.com/gophercloud/gophercloud/pull/1875) -* Fixed `compute/v2/extensions/extendedserverattributes.ServerAttributesExt.Userdata` JSON tag [GH-1881](https://github.com/gophercloud/gophercloud/pull/1881) - -## 0.8.0 (February 8, 2020) - -UPGRADE NOTES - -* The behavior of `keymanager/v1/acls.SetOpts` has changed. Instead of a struct, it is now `[]SetOpt`. See [GH-1816](https://github.com/gophercloud/gophercloud/pull/1816) for implementation details. - -IMPROVEMENTS - -* The result of `containerinfra/v1/clusters.Resize` now returns only the UUID when calling `Extract`. This is a backwards-breaking change from the previous struct that was returned [GH-1649](https://github.com/gophercloud/gophercloud/pull/1649) -* Added `compute/v2/extensions/shelveunshelve.Shelve` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799) -* Added `compute/v2/extensions/shelveunshelve.ShelveOffload` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799) -* Added `compute/v2/extensions/shelveunshelve.Unshelve` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799) -* Added `containerinfra/v1/nodegroups.Get` [GH-1774](https://github.com/gophercloud/gophercloud/pull/1774) -* Added `containerinfra/v1/nodegroups.List` [GH-1774](https://github.com/gophercloud/gophercloud/pull/1774) -* Added `orchestration/v1/resourcetypes.List` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806) -* Added `orchestration/v1/resourcetypes.GetSchema` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806) -* Added `orchestration/v1/resourcetypes.GenerateTemplate` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806) -* Added `keymanager/v1/acls.SetOpt` and changed `keymanager/v1/acls.SetOpts` to `[]SetOpt` [GH-1816](https://github.com/gophercloud/gophercloud/pull/1816) -* Added `blockstorage/apiversions.List` [GH-458](https://github.com/gophercloud/gophercloud/pull/458) -* Added `blockstorage/apiversions.Get` [GH-458](https://github.com/gophercloud/gophercloud/pull/458) -* Added `StatusCodeError` interface and `GetStatusCode` convenience method [GH-1820](https://github.com/gophercloud/gophercloud/pull/1820) -* Added pagination support to `compute/v2/extensions/usage.SingleTenant` [GH-1819](https://github.com/gophercloud/gophercloud/pull/1819) -* Added pagination support to `compute/v2/extensions/usage.AllTenants` [GH-1819](https://github.com/gophercloud/gophercloud/pull/1819) -* Added `placement/v1/resourceproviders.List` [GH-1815](https://github.com/gophercloud/gophercloud/pull/1815) -* Allow `CreateMemberOptsBuilder` to be passed in `loadbalancer/v2/pools.Create` [GH-1822](https://github.com/gophercloud/gophercloud/pull/1822) -* Added `Backup` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824) -* Added `MonitorAddress` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824) -* Added `MonitorPort` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824) -* Changed `Impersonation` to a non-required field in `identity/v3/extensions/trusts.CreateOpts` [GH-1818](https://github.com/gophercloud/gophercloud/pull/1818) -* Added `InsertHeaders` to `loadbalancer/v2/listeners.UpdateOpts` [GH-1835](https://github.com/gophercloud/gophercloud/pull/1835) -* Added `NUMATopology` to `baremetalintrospection/v1/introspection.Data` [GH-1842](https://github.com/gophercloud/gophercloud/pull/1842) -* Added `placement/v1/resourceproviders.Create` [GH-1841](https://github.com/gophercloud/gophercloud/pull/1841) -* Added `blockstorage/extensions/volumeactions.UploadImageOpts.Visibility` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873) -* Added `blockstorage/extensions/volumeactions.UploadImageOpts.Protected` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873) -* Added `blockstorage/extensions/volumeactions.VolumeImage.Visibility` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873) -* Added `blockstorage/extensions/volumeactions.VolumeImage.Protected` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873) - -BUG FIXES - -* Changed `sort_key` to `sort_keys` in ` workflow/v2/crontriggers.ListOpts` [GH-1809](https://github.com/gophercloud/gophercloud/pull/1809) -* Allow `blockstorage/extensions/schedulerstats.Capabilities.MaxOverSubscriptionRatio` to accept both string and int/float responses [GH-1817](https://github.com/gophercloud/gophercloud/pull/1817) -* Fixed bug in `NewLoadBalancerV2` for situations when the LBaaS service was advertised without a `/v2.0` endpoint [GH-1829](https://github.com/gophercloud/gophercloud/pull/1829) -* Fixed JSON tags in `baremetal/v1/ports.UpdateOperation` [GH-1840](https://github.com/gophercloud/gophercloud/pull/1840) -* Fixed JSON tags in `networking/v2/extensions/lbaas/vips.commonResult.Extract()` [GH-1840](https://github.com/gophercloud/gophercloud/pull/1840) - -## 0.7.0 (December 3, 2019) - -IMPROVEMENTS - -* Allow a token to be used directly for authentication instead of generating a new token based on a given token [GH-1752](https://github.com/gophercloud/gophercloud/pull/1752) -* Moved `tags.ServerTagsExt` to servers.TagsExt` [GH-1760](https://github.com/gophercloud/gophercloud/pull/1760) -* Added `tags`, `tags-any`, `not-tags`, and `not-tags-any` to `compute/v2/servers.ListOpts` [GH-1759](https://github.com/gophercloud/gophercloud/pull/1759) -* Added `AccessRule` to `identity/v3/applicationcredentials` [GH-1758](https://github.com/gophercloud/gophercloud/pull/1758) -* Gophercloud no longer returns an error when multiple endpoints are found. Instead, it will choose the first endpoint and discard the others [GH-1766](https://github.com/gophercloud/gophercloud/pull/1766) -* Added `networking/v2/extensions/fwaas_v2/rules.Create` [GH-1768](https://github.com/gophercloud/gophercloud/pull/1768) -* Added `networking/v2/extensions/fwaas_v2/rules.Delete` [GH-1771](https://github.com/gophercloud/gophercloud/pull/1771) -* Added `loadbalancer/v2/providers.List` [GH-1765](https://github.com/gophercloud/gophercloud/pull/1765) -* Added `networking/v2/extensions/fwaas_v2/rules.Get` [GH-1772](https://github.com/gophercloud/gophercloud/pull/1772) -* Added `networking/v2/extensions/fwaas_v2/rules.Update` [GH-1776](https://github.com/gophercloud/gophercloud/pull/1776) -* Added `networking/v2/extensions/fwaas_v2/rules.List` [GH-1783](https://github.com/gophercloud/gophercloud/pull/1783) -* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.CreateOpts` [GH-1785](https://github.com/gophercloud/gophercloud/pull/1785) -* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.UpdateOpts` [GH-1786](https://github.com/gophercloud/gophercloud/pull/1786) -* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.Monitor` [GH-1787](https://github.com/gophercloud/gophercloud/pull/1787) -* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.ListOpts` [GH-1788](https://github.com/gophercloud/gophercloud/pull/1788) -* Updated `go.mod` dependencies, specifically to account for CVE-2019-11840 with `golang.org/x/crypto` [GH-1793](https://github.com/gophercloud/gophercloud/pull/1788) - -## 0.6.0 (October 17, 2019) - -UPGRADE NOTES - -* The way reauthentication works has been refactored. This should not cause a problem, but please report bugs if it does. See [GH-1746](https://github.com/gophercloud/gophercloud/pull/1746) for more information. - -IMPROVEMENTS - -* Added `networking/v2/extensions/quotas.Get` [GH-1742](https://github.com/gophercloud/gophercloud/pull/1742) -* Added `networking/v2/extensions/quotas.Update` [GH-1747](https://github.com/gophercloud/gophercloud/pull/1747) -* Refactored the reauthentication implementation to use goroutines and added a check to prevent an infinite loop in certain situations. [GH-1746](https://github.com/gophercloud/gophercloud/pull/1746) - -BUG FIXES - -* Changed `Flavor` to `FlavorID` in `loadbalancer/v2/loadbalancers` [GH-1744](https://github.com/gophercloud/gophercloud/pull/1744) -* Changed `Flavor` to `FlavorID` in `networking/v2/extensions/lbaas_v2/loadbalancers` [GH-1744](https://github.com/gophercloud/gophercloud/pull/1744) -* The `go-yaml` dependency was updated to `v2.2.4` to fix possible DDOS vulnerabilities [GH-1751](https://github.com/gophercloud/gophercloud/pull/1751) - -## 0.5.0 (October 13, 2019) - -IMPROVEMENTS - -* Added `VolumeType` to `compute/v2/extensions/bootfromvolume.BlockDevice`[GH-1690](https://github.com/gophercloud/gophercloud/pull/1690) -* Added `networking/v2/extensions/layer3/portforwarding.List` [GH-1688](https://github.com/gophercloud/gophercloud/pull/1688) -* Added `networking/v2/extensions/layer3/portforwarding.Get` [GH-1698](https://github.com/gophercloud/gophercloud/pull/1696) -* Added `compute/v2/extensions/tags.ReplaceAll` [GH-1696](https://github.com/gophercloud/gophercloud/pull/1696) -* Added `compute/v2/extensions/tags.Add` [GH-1696](https://github.com/gophercloud/gophercloud/pull/1696) -* Added `networking/v2/extensions/layer3/portforwarding.Update` [GH-1703](https://github.com/gophercloud/gophercloud/pull/1703) -* Added `ExtractDomain` method to token results in `identity/v3/tokens` [GH-1712](https://github.com/gophercloud/gophercloud/pull/1712) -* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.CreateOpts` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710) -* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.UpdateOpts` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710) -* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.Listener` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710) -* Added `compute/v2/extensions/tags.Add` [GH-1695](https://github.com/gophercloud/gophercloud/pull/1695) -* Added `compute/v2/extensions/tags.ReplaceAll` [GH-1694](https://github.com/gophercloud/gophercloud/pull/1694) -* Added `compute/v2/extensions/tags.Delete` [GH-1699](https://github.com/gophercloud/gophercloud/pull/1699) -* Added `compute/v2/extensions/tags.DeleteAll` [GH-1700](https://github.com/gophercloud/gophercloud/pull/1700) -* Added `ImageStatusImporting` as an image status [GH-1725](https://github.com/gophercloud/gophercloud/pull/1725) -* Added `ByPath` to `baremetalintrospection/v1/introspection.RootDiskType` [GH-1730](https://github.com/gophercloud/gophercloud/pull/1730) -* Added `AttachedVolumes` to `compute/v2/servers.Server` [GH-1732](https://github.com/gophercloud/gophercloud/pull/1732) -* Enable unmarshaling server tags to a `compute/v2/servers.Server` struct [GH-1734] -* Allow setting an empty members list in `loadbalancer/v2/pools.BatchUpdateMembers` [GH-1736](https://github.com/gophercloud/gophercloud/pull/1736) -* Allow unsetting members' subnet ID and name in `loadbalancer/v2/pools.BatchUpdateMemberOpts` [GH-1738](https://github.com/gophercloud/gophercloud/pull/1738) - -BUG FIXES - -* Changed struct type for options in `networking/v2/extensions/lbaas_v2/listeners` to `UpdateOptsBuilder` interface instead of specific UpdateOpts type [GH-1705](https://github.com/gophercloud/gophercloud/pull/1705) -* Changed struct type for options in `networking/v2/extensions/lbaas_v2/loadbalancers` to `UpdateOptsBuilder` interface instead of specific UpdateOpts type [GH-1706](https://github.com/gophercloud/gophercloud/pull/1706) -* Fixed issue with `blockstorage/v1/volumes.Create` where the response was expected to be 202 [GH-1720](https://github.com/gophercloud/gophercloud/pull/1720) -* Changed `DefaultTlsContainerRef` from `string` to `*string` in `loadbalancer/v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723) -* Changed `SniContainerRefs` from `[]string{}` to `*[]string{}` in `loadbalancer/v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723) -* Changed `DefaultTlsContainerRef` from `string` to `*string` in `networking/v2/extensions/lbaas_v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723) -* Changed `SniContainerRefs` from `[]string{}` to `*[]string{}` in `networking/v2/extensions/lbaas_v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723) - - -## 0.4.0 (September 3, 2019) - -IMPROVEMENTS - -* Added `blockstorage/extensions/quotasets.results.QuotaSet.Groups` [GH-1668](https://github.com/gophercloud/gophercloud/pull/1668) -* Added `blockstorage/extensions/quotasets.results.QuotaUsageSet.Groups` [GH-1668](https://github.com/gophercloud/gophercloud/pull/1668) -* Added `containerinfra/v1/clusters.CreateOpts.FixedNetwork` [GH-1674](https://github.com/gophercloud/gophercloud/pull/1674) -* Added `containerinfra/v1/clusters.CreateOpts.FixedSubnet` [GH-1676](https://github.com/gophercloud/gophercloud/pull/1676) -* Added `containerinfra/v1/clusters.CreateOpts.FloatingIPEnabled` [GH-1677](https://github.com/gophercloud/gophercloud/pull/1677) -* Added `CreatedAt` and `UpdatedAt` to `loadbalancers/v2/loadbalancers.LoadBalancer` [GH-1681](https://github.com/gophercloud/gophercloud/pull/1681) -* Added `networking/v2/extensions/layer3/portforwarding.Create` [GH-1651](https://github.com/gophercloud/gophercloud/pull/1651) -* Added `networking/v2/extensions/agents.ListDHCPNetworks` [GH-1686](https://github.com/gophercloud/gophercloud/pull/1686) -* Added `networking/v2/extensions/layer3/portforwarding.Delete` [GH-1652](https://github.com/gophercloud/gophercloud/pull/1652) -* Added `compute/v2/extensions/tags.List` [GH-1679](https://github.com/gophercloud/gophercloud/pull/1679) -* Added `compute/v2/extensions/tags.Check` [GH-1679](https://github.com/gophercloud/gophercloud/pull/1679) - -BUG FIXES - -* Changed `identity/v3/endpoints.ListOpts.RegionID` from `int` to `string` [GH-1664](https://github.com/gophercloud/gophercloud/pull/1664) -* Fixed issue where older time formats in some networking APIs/resources were unable to be parsed [GH-1671](https://github.com/gophercloud/gophercloud/pull/1664) -* Changed `SATA`, `SCSI`, and `SAS` types to `InterfaceType` in `baremetal/v1/nodes` [GH-1683] - -## 0.3.0 (July 31, 2019) - -IMPROVEMENTS - -* Added `baremetal/apiversions.List` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577) -* Added `baremetal/apiversions.Get` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577) -* Added `compute/v2/extensions/servergroups.CreateOpts.Policy` [GH-1636](https://github.com/gophercloud/gophercloud/pull/1636) -* Added `identity/v3/extensions/trusts.Create` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644) -* Added `identity/v3/extensions/trusts.Delete` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644) -* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/layer3/floatingips.FloatingIP` [GH-1647](https://github.com/gophercloud/gophercloud/issues/1646) -* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/security/groups.SecGroup` [GH-1654](https://github.com/gophercloud/gophercloud/issues/1654) -* Added `CreatedAt` and `UpdatedAt` to `networking/v2/networks.Network` [GH-1657](https://github.com/gophercloud/gophercloud/issues/1657) -* Added `keymanager/v1/containers.CreateSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659) -* Added `keymanager/v1/containers.DeleteSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659) -* Added `sharedfilesystems/v2/shares.GetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) -* Added `sharedfilesystems/v2/shares.GetMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) -* Added `sharedfilesystems/v2/shares.SetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) -* Added `sharedfilesystems/v2/shares.UpdateMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) -* Added `sharedfilesystems/v2/shares.DeleteMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) -* Added `sharedfilesystems/v2/sharetypes.IDFromName` [GH-1662](https://github.com/gophercloud/gophercloud/issues/1662) - - - -BUG FIXES - -* Changed `baremetal/v1/nodes.CleanStep.Args` from `map[string]string` to `map[string]interface{}` [GH-1638](https://github.com/gophercloud/gophercloud/pull/1638) -* Removed `URLPath` and `ExpectedCodes` from `loadbalancer/v2/monitors.ToMonitorCreateMap` since Octavia now provides default values when these fields are not specified [GH-1640](https://github.com/gophercloud/gophercloud/pull/1540) - - -## 0.2.0 (June 17, 2019) - -IMPROVEMENTS - -* Added `networking/v2/extensions/qos/rules.ListBandwidthLimitRules` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) -* Added `networking/v2/extensions/qos/rules.GetBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) -* Added `networking/v2/extensions/qos/rules.CreateBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) -* Added `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` [GH-1589](https://github.com/gophercloud/gophercloud/pull/1589) -* Added `networking/v2/extensions/qos/rules.DeleteBandwidthLimitRule` [GH-1590](https://github.com/gophercloud/gophercloud/pull/1590) -* Added `networking/v2/extensions/qos/policies.List` [GH-1591](https://github.com/gophercloud/gophercloud/pull/1591) -* Added `networking/v2/extensions/qos/policies.Get` [GH-1593](https://github.com/gophercloud/gophercloud/pull/1593) -* Added `networking/v2/extensions/qos/rules.ListDSCPMarkingRules` [GH-1594](https://github.com/gophercloud/gophercloud/pull/1594) -* Added `networking/v2/extensions/qos/policies.Create` [GH-1595](https://github.com/gophercloud/gophercloud/pull/1595) -* Added `compute/v2/extensions/diagnostics.Get` [GH-1592](https://github.com/gophercloud/gophercloud/pull/1592) -* Added `networking/v2/extensions/qos/policies.Update` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603) -* Added `networking/v2/extensions/qos/policies.Delete` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603) -* Added `networking/v2/extensions/qos/rules.CreateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605) -* Added `networking/v2/extensions/qos/rules.UpdateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605) -* Added `networking/v2/extensions/qos/rules.GetDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609) -* Added `networking/v2/extensions/qos/rules.DeleteDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609) -* Added `networking/v2/extensions/qos/rules.ListMinimumBandwidthRules` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) -* Added `networking/v2/extensions/qos/rules.GetMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) -* Added `networking/v2/extensions/qos/rules.CreateMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) -* Added `Hostname` to `baremetalintrospection/v1/introspection.Data` [GH-1627](https://github.com/gophercloud/gophercloud/pull/1627) -* Added `networking/v2/extensions/qos/rules.UpdateMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624) -* Added `networking/v2/extensions/qos/rules.DeleteMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624) -* Added `networking/v2/extensions/qos/ruletypes.GetRuleType` [GH-1625](https://github.com/gophercloud/gophercloud/pull/1625) -* Added `Extra` to `baremetalintrospection/v1/introspection.Data` [GH-1611](https://github.com/gophercloud/gophercloud/pull/1611) -* Added `blockstorage/extensions/volumeactions.SetImageMetadata` [GH-1621](https://github.com/gophercloud/gophercloud/pull/1621) - -BUG FIXES - -* Updated `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` to use return code 200 [GH-1606](https://github.com/gophercloud/gophercloud/pull/1606) -* Fixed bug in `compute/v2/extensions/schedulerhints.SchedulerHints.Query` where contents will now be marshalled to a string [GH-1620](https://github.com/gophercloud/gophercloud/pull/1620) - -## 0.1.0 (May 27, 2019) - -Initial tagged release. diff --git a/vendor/github.com/gophercloud/gophercloud/README.md b/vendor/github.com/gophercloud/gophercloud/README.md deleted file mode 100644 index 4e6e57da..00000000 --- a/vendor/github.com/gophercloud/gophercloud/README.md +++ /dev/null @@ -1,172 +0,0 @@ -# Gophercloud: an OpenStack SDK for Go -[![Coverage Status](https://coveralls.io/repos/github/gophercloud/gophercloud/badge.svg?branch=v1)](https://coveralls.io/github/gophercloud/gophercloud?branch=v1) - -Gophercloud is an OpenStack Go SDK. - -## Useful links - -* [Reference documentation](http://godoc.org/github.com/gophercloud/gophercloud) -* [Effective Go](https://golang.org/doc/effective_go.html) - -## How to install - -Reference a Gophercloud package in your code: - -```go -import "github.com/gophercloud/gophercloud" -``` - -Then update your `go.mod`: - -```shell -go mod tidy -``` - -## Getting started - -### Credentials - -Because you'll be hitting an API, you will need to retrieve your OpenStack -credentials and either store them in a `clouds.yaml` file, as environment -variables, or in your local Go files. The first method is recommended because -it decouples credential information from source code, allowing you to push the -latter to your version control system without any security risk. - -You will need to retrieve the following: - -* A valid Keystone identity URL -* Credentials. These can be a username/password combo, a set of Application - Credentials, a pre-generated token, or any other supported authentication - mechanism. - -For users who have the OpenStack dashboard installed, there's a shortcut. If -you visit the `project/api_access` path in Horizon and click on the -"Download OpenStack RC File" button at the top right hand corner, you can -download either a `clouds.yaml` file or an `openrc` bash file that exports all -of your access details to environment variables. To use the `clouds.yaml` file, -place it at `~/.config/openstack/clouds.yaml`. To use the `openrc` file, run -`source openrc` and you will be prompted for your password. - -### Authentication - -Once you have access to your credentials, you can begin plugging them into -Gophercloud. The next step is authentication, which is handled by a base -"Provider" struct. There are number of ways to construct such a struct. - -**With `gophercloud/utils`** - -The [github.com/gophercloud/utils](https://github.com/gophercloud/utils) -library provides the `clientconfig` package to simplify authentication. It -provides additional functionality, such as the ability to read `clouds.yaml` -files. To generate a "Provider" struct using the `clientconfig` package: - -```go -import ( - "github.com/gophercloud/utils/openstack/clientconfig" -) - -// You can also skip configuring this and instead set 'OS_CLOUD' in your -// environment -opts := new(clientconfig.ClientOpts) -opts.Cloud = "devstack-admin" - -provider, err := clientconfig.AuthenticatedClient(opts) -``` - -A provider client is a top-level client that all of your OpenStack service -clients derive from. The provider contains all of the authentication details -that allow your Go code to access the API - such as the base URL and token ID. - -Once we have a base Provider, we inject it as a dependency into each OpenStack -service. For example, in order to work with the Compute API, we need a Compute -service client. This can be created like so: - -```go -client, err := clientconfig.NewServiceClient("compute", opts) -``` - -**Without `gophercloud/utils`** - -> *Note* -> gophercloud doesn't provide support for `clouds.yaml` file so you need to -> implement this functionality yourself if you don't wish to use -> `gophercloud/utils`. - -You can also generate a "Provider" struct without using the `clientconfig` -package from `gophercloud/utils`. To do this, you can either pass in your -credentials explicitly or tell Gophercloud to use environment variables: - -```go -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack" -) - -// Option 1: Pass in the values yourself -opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - Username: "{username}", - Password: "{password}", -} - -// Option 2: Use a utility function to retrieve all your environment variables -opts, err := openstack.AuthOptionsFromEnv() -``` - -Once you have the `opts` variable, you can pass it in and get back a -`ProviderClient` struct: - -```go -provider, err := openstack.AuthenticatedClient(opts) -``` - -As above, you can then use this provider client to generate a service client -for a particular OpenStack service: - -```go -client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ - Region: os.Getenv("OS_REGION_NAME"), -}) -``` - -### Provision a server - -We can use the Compute service client generated above for any Compute API -operation we want. In our case, we want to provision a new server. To do this, -we invoke the `Create` method and pass in the flavor ID (hardware -specification) and image ID (operating system) we're interested in: - -```go -import "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" - -server, err := servers.Create(client, servers.CreateOpts{ - Name: "My new server!", - FlavorRef: "flavor_id", - ImageRef: "image_id", -}).Extract() -``` - -The above code sample creates a new server with the parameters, and embodies the -new resource in the `server` variable (a -[`servers.Server`](http://godoc.org/github.com/gophercloud/gophercloud) struct). - -## Advanced Usage - -Have a look at the [FAQ](./docs/FAQ.md) for some tips on customizing the way Gophercloud works. - -## Backwards-Compatibility Guarantees - -Gophercloud versioning follows [semver](https://semver.org/spec/v2.0.0.html). - -Before `v1.0.0`, there were no guarantees. Starting with v1, there will be no breaking changes within a major release. - -See the [Release instructions](./RELEASE.md). - -## Contributing - -See the [contributing guide](./.github/CONTRIBUTING.md). - -## Help and feedback - -If you're struggling with something or have spotted a potential bug, feel free -to submit an issue to our [bug tracker](https://github.com/gophercloud/gophercloud/issues). diff --git a/vendor/github.com/gophercloud/gophercloud/RELEASE.md b/vendor/github.com/gophercloud/gophercloud/RELEASE.md deleted file mode 100644 index 6490ed88..00000000 --- a/vendor/github.com/gophercloud/gophercloud/RELEASE.md +++ /dev/null @@ -1,79 +0,0 @@ -# Gophercloud release - -## Contributions - -### The semver label - -Gophercloud follows [semver](https://semver.org/). - -Each Pull request must have a label indicating its impact on the API: -* `semver:patch` for changes that don't impact the API -* `semver:minor` for changes that impact the API in a backwards-compatible fashion -* `semver:major` for changes that introduce a breaking change in the API - -Automation prevents merges if the label is not present. - -### Metadata - -The release notes for a given release are generated based on the PR title: make -sure that the PR title is descriptive. - -## Release of a new version - -Requirements: -* [`gh`](https://github.com/cli/cli) -* [`jq`](https://stedolan.github.io/jq/) - -### Step 1: Collect all PRs since the last release - -Supposing that the base release is `v1.2.0`: - -``` -for commit_sha in $(git log --pretty=format:"%h" v1.2.0..HEAD); do - gh pr list --search "$commit_sha" --state merged --json number,title,labels,url -done | jq '.[]' | jq --slurp 'unique_by(.number)' > prs.json -``` - -This JSON file will be useful later. - -### Step 2: Determine the version - -In order to determine the version of the next release, we first check that no incompatible change is detected in the code that has been merged since the last release. This step can be automated with the `gorelease` tool: - -```shell -gorelease | grep -B2 -A0 '^## incompatible changes' -``` - -If the tool detects incompatible changes outside a `testing` package, then the bump is major. - -Next, we check all PRs merged since the last release using the file `prs.json` that we generated above. - -* Find PRs labeled with `semver:major`: `jq 'map(select(contains({labels: [{name: "semver:major"}]}) ))' prs.json` -* Find PRs labeled with `semver:minor`: `jq 'map(select(contains({labels: [{name: "semver:minor"}]}) ))' prs.json` - -The highest semver descriptor determines the release bump. - -### Step 3: Release notes and version string - -Once all PRs have a sensible title, generate the release notes: - -```shell -jq -r '.[] | "* [GH-\(.number)](\(.url)) \(.title)"' prs.json -``` - -Add that to the top of `CHANGELOG.md`. Also add any information that could be useful to consumers willing to upgrade. - -**Set the new version string in the `DefaultUserAgent` constant in `provider_client.go`.** - -Create a PR with these two changes. The new PR should be labeled with the semver label corresponding to the type of bump. - -### Step 3: Git tag and Github release - -The Go mod system relies on Git tags. In order to simulate a review mechanism, we rely on Github to create the tag through the Release mechanism. - -* [Prepare a new release](https://github.com/gophercloud/gophercloud/releases/new) -* Let Github generate the release notes by clicking on Generate release notes -* Click on **Save draft** -* Ask another Gophercloud maintainer to review and publish the release - -_Note: never change a release or force-push a tag. Tags are almost immediately picked up by the Go proxy and changing the commit it points to will be detected as tampering._ diff --git a/vendor/github.com/gophercloud/gophercloud/auth_options.go b/vendor/github.com/gophercloud/gophercloud/auth_options.go deleted file mode 100644 index 335ce879..00000000 --- a/vendor/github.com/gophercloud/gophercloud/auth_options.go +++ /dev/null @@ -1,514 +0,0 @@ -package gophercloud - -/* -AuthOptions stores information needed to authenticate to an OpenStack Cloud. -You can populate one manually, or use a provider's AuthOptionsFromEnv() function -to read relevant information from the standard environment variables. Pass one -to a provider's AuthenticatedClient function to authenticate and obtain a -ProviderClient representing an active session on that provider. - -Its fields are the union of those recognized by each identity implementation and -provider. - -An example of manually providing authentication information: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - Username: "{username}", - Password: "{password}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(opts) - -An example of using AuthOptionsFromEnv(), where the environment variables can -be read from a file, such as a standard openrc file: - - opts, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClient(opts) -*/ -type AuthOptions struct { - // IdentityEndpoint specifies the HTTP endpoint that is required to work with - // the Identity API of the appropriate version. While it's ultimately needed by - // all of the identity services, it will often be populated by a provider-level - // function. - // - // The IdentityEndpoint is typically referred to as the "auth_url" or - // "OS_AUTH_URL" in the information provided by the cloud operator. - IdentityEndpoint string `json:"-"` - - // Username is required if using Identity V2 API. Consult with your provider's - // control panel to discover your account's username. In Identity V3, either - // UserID or a combination of Username and DomainID or DomainName are needed. - Username string `json:"username,omitempty"` - UserID string `json:"-"` - - Password string `json:"password,omitempty"` - - // Passcode is used in TOTP authentication method - Passcode string `json:"passcode,omitempty"` - - // At most one of DomainID and DomainName must be provided if using Username - // with Identity V3. Otherwise, either are optional. - DomainID string `json:"-"` - DomainName string `json:"name,omitempty"` - - // The TenantID and TenantName fields are optional for the Identity V2 API. - // The same fields are known as project_id and project_name in the Identity - // V3 API, but are collected as TenantID and TenantName here in both cases. - // Some providers allow you to specify a TenantName instead of the TenantId. - // Some require both. Your provider's authentication policies will determine - // how these fields influence authentication. - // If DomainID or DomainName are provided, they will also apply to TenantName. - // It is not currently possible to authenticate with Username and a Domain - // and scope to a Project in a different Domain by using TenantName. To - // accomplish that, the ProjectID will need to be provided as the TenantID - // option. - TenantID string `json:"tenantId,omitempty"` - TenantName string `json:"tenantName,omitempty"` - - // AllowReauth should be set to true if you grant permission for Gophercloud to - // cache your credentials in memory, and to allow Gophercloud to attempt to - // re-authenticate automatically if/when your token expires. If you set it to - // false, it will not cache these settings, but re-authentication will not be - // possible. This setting defaults to false. - // - // NOTE: The reauth function will try to re-authenticate endlessly if left - // unchecked. The way to limit the number of attempts is to provide a custom - // HTTP client to the provider client and provide a transport that implements - // the RoundTripper interface and stores the number of failed retries. For an - // example of this, see here: - // https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311 - AllowReauth bool `json:"-"` - - // TokenID allows users to authenticate (possibly as another user) with an - // authentication token ID. - TokenID string `json:"-"` - - // Scope determines the scoping of the authentication request. - Scope *AuthScope `json:"-"` - - // Authentication through Application Credentials requires supplying name, project and secret - // For project we can use TenantID - ApplicationCredentialID string `json:"-"` - ApplicationCredentialName string `json:"-"` - ApplicationCredentialSecret string `json:"-"` -} - -// AuthScope allows a created token to be limited to a specific domain or project. -type AuthScope struct { - ProjectID string - ProjectName string - DomainID string - DomainName string - System bool -} - -// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder -// interface in the v2 tokens package -func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { - // Populate the request map. - authMap := make(map[string]interface{}) - - if opts.Username != "" { - if opts.Password != "" { - authMap["passwordCredentials"] = map[string]interface{}{ - "username": opts.Username, - "password": opts.Password, - } - } else { - return nil, ErrMissingInput{Argument: "Password"} - } - } else if opts.TokenID != "" { - authMap["token"] = map[string]interface{}{ - "id": opts.TokenID, - } - } else { - return nil, ErrMissingInput{Argument: "Username"} - } - - if opts.TenantID != "" { - authMap["tenantId"] = opts.TenantID - } - if opts.TenantName != "" { - authMap["tenantName"] = opts.TenantName - } - - return map[string]interface{}{"auth": authMap}, nil -} - -// ToTokenV3CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder -// interface in the v3 tokens package -func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { - type domainReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - } - - type projectReq struct { - Domain *domainReq `json:"domain,omitempty"` - Name *string `json:"name,omitempty"` - ID *string `json:"id,omitempty"` - } - - type userReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Password *string `json:"password,omitempty"` - Passcode *string `json:"passcode,omitempty"` - Domain *domainReq `json:"domain,omitempty"` - } - - type passwordReq struct { - User userReq `json:"user"` - } - - type tokenReq struct { - ID string `json:"id"` - } - - type applicationCredentialReq struct { - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - User *userReq `json:"user,omitempty"` - Secret *string `json:"secret,omitempty"` - } - - type totpReq struct { - User *userReq `json:"user,omitempty"` - } - - type identityReq struct { - Methods []string `json:"methods"` - Password *passwordReq `json:"password,omitempty"` - Token *tokenReq `json:"token,omitempty"` - ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"` - TOTP *totpReq `json:"totp,omitempty"` - } - - type authReq struct { - Identity identityReq `json:"identity"` - } - - type request struct { - Auth authReq `json:"auth"` - } - - // Populate the request structure based on the provided arguments. Create and return an error - // if insufficient or incompatible information is present. - var req request - - if opts.Password == "" && opts.Passcode == "" { - if opts.TokenID != "" { - // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication - // parameters. - if opts.Username != "" { - return nil, ErrUsernameWithToken{} - } - if opts.UserID != "" { - return nil, ErrUserIDWithToken{} - } - if opts.DomainID != "" { - return nil, ErrDomainIDWithToken{} - } - if opts.DomainName != "" { - return nil, ErrDomainNameWithToken{} - } - - // Configure the request for Token authentication. - req.Auth.Identity.Methods = []string{"token"} - req.Auth.Identity.Token = &tokenReq{ - ID: opts.TokenID, - } - - } else if opts.ApplicationCredentialID != "" { - // Configure the request for ApplicationCredentialID authentication. - // https://github.com/openstack/keystoneauth/blob/stable/rocky/keystoneauth1/identity/v3/application_credential.py#L48-L67 - // There are three kinds of possible application_credential requests - // 1. application_credential id + secret - // 2. application_credential name + secret + user_id - // 3. application_credential name + secret + username + domain_id / domain_name - if opts.ApplicationCredentialSecret == "" { - return nil, ErrAppCredMissingSecret{} - } - req.Auth.Identity.Methods = []string{"application_credential"} - req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ - ID: &opts.ApplicationCredentialID, - Secret: &opts.ApplicationCredentialSecret, - } - } else if opts.ApplicationCredentialName != "" { - if opts.ApplicationCredentialSecret == "" { - return nil, ErrAppCredMissingSecret{} - } - - var userRequest *userReq - - if opts.UserID != "" { - // UserID could be used without the domain information - userRequest = &userReq{ - ID: &opts.UserID, - } - } - - if userRequest == nil && opts.Username == "" { - // Make sure that Username or UserID are provided - return nil, ErrUsernameOrUserID{} - } - - if userRequest == nil && opts.DomainID != "" { - userRequest = &userReq{ - Name: &opts.Username, - Domain: &domainReq{ID: &opts.DomainID}, - } - } - - if userRequest == nil && opts.DomainName != "" { - userRequest = &userReq{ - Name: &opts.Username, - Domain: &domainReq{Name: &opts.DomainName}, - } - } - - // Make sure that DomainID or DomainName are provided among Username - if userRequest == nil { - return nil, ErrDomainIDOrDomainName{} - } - - req.Auth.Identity.Methods = []string{"application_credential"} - req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ - Name: &opts.ApplicationCredentialName, - User: userRequest, - Secret: &opts.ApplicationCredentialSecret, - } - } else { - // If no password or token ID or ApplicationCredential are available, authentication can't continue. - return nil, ErrMissingPassword{} - } - } else { - // Password authentication. - if opts.Password != "" { - req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "password") - } - - // TOTP authentication. - if opts.Passcode != "" { - req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "totp") - } - - // At least one of Username and UserID must be specified. - if opts.Username == "" && opts.UserID == "" { - return nil, ErrUsernameOrUserID{} - } - - if opts.Username != "" { - // If Username is provided, UserID may not be provided. - if opts.UserID != "" { - return nil, ErrUsernameOrUserID{} - } - - // Either DomainID or DomainName must also be specified. - if opts.DomainID == "" && opts.DomainName == "" { - return nil, ErrDomainIDOrDomainName{} - } - - if opts.DomainID != "" { - if opts.DomainName != "" { - return nil, ErrDomainIDOrDomainName{} - } - - // Configure the request for Username and Password authentication with a DomainID. - if opts.Password != "" { - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: &opts.Password, - Domain: &domainReq{ID: &opts.DomainID}, - }, - } - } - if opts.Passcode != "" { - req.Auth.Identity.TOTP = &totpReq{ - User: &userReq{ - Name: &opts.Username, - Passcode: &opts.Passcode, - Domain: &domainReq{ID: &opts.DomainID}, - }, - } - } - } - - if opts.DomainName != "" { - // Configure the request for Username and Password authentication with a DomainName. - if opts.Password != "" { - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - Name: &opts.Username, - Password: &opts.Password, - Domain: &domainReq{Name: &opts.DomainName}, - }, - } - } - - if opts.Passcode != "" { - req.Auth.Identity.TOTP = &totpReq{ - User: &userReq{ - Name: &opts.Username, - Passcode: &opts.Passcode, - Domain: &domainReq{Name: &opts.DomainName}, - }, - } - } - } - } - - if opts.UserID != "" { - // If UserID is specified, neither DomainID nor DomainName may be. - if opts.DomainID != "" { - return nil, ErrDomainIDWithUserID{} - } - if opts.DomainName != "" { - return nil, ErrDomainNameWithUserID{} - } - - // Configure the request for UserID and Password authentication. - if opts.Password != "" { - req.Auth.Identity.Password = &passwordReq{ - User: userReq{ - ID: &opts.UserID, - Password: &opts.Password, - }, - } - } - - if opts.Passcode != "" { - req.Auth.Identity.TOTP = &totpReq{ - User: &userReq{ - ID: &opts.UserID, - Passcode: &opts.Passcode, - }, - } - } - } - } - - b, err := BuildRequestBody(req, "") - if err != nil { - return nil, err - } - - if len(scope) != 0 { - b["auth"].(map[string]interface{})["scope"] = scope - } - - return b, nil -} - -// ToTokenV3ScopeMap builds a scope from AuthOptions and satisfies interface in -// the v3 tokens package. -func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { - // For backwards compatibility. - // If AuthOptions.Scope was not set, try to determine it. - // This works well for common scenarios. - if opts.Scope == nil { - opts.Scope = new(AuthScope) - if opts.TenantID != "" { - opts.Scope.ProjectID = opts.TenantID - } else { - if opts.TenantName != "" { - opts.Scope.ProjectName = opts.TenantName - opts.Scope.DomainID = opts.DomainID - opts.Scope.DomainName = opts.DomainName - } - } - } - - if opts.Scope.System { - return map[string]interface{}{ - "system": map[string]interface{}{ - "all": true, - }, - }, nil - } - - if opts.Scope.ProjectName != "" { - // ProjectName provided: either DomainID or DomainName must also be supplied. - // ProjectID may not be supplied. - if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" { - return nil, ErrScopeDomainIDOrDomainName{} - } - if opts.Scope.ProjectID != "" { - return nil, ErrScopeProjectIDOrProjectName{} - } - - if opts.Scope.DomainID != "" { - // ProjectName + DomainID - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"id": &opts.Scope.DomainID}, - }, - }, nil - } - - if opts.Scope.DomainName != "" { - // ProjectName + DomainName - return map[string]interface{}{ - "project": map[string]interface{}{ - "name": &opts.Scope.ProjectName, - "domain": map[string]interface{}{"name": &opts.Scope.DomainName}, - }, - }, nil - } - } else if opts.Scope.ProjectID != "" { - // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. - if opts.Scope.DomainID != "" { - return nil, ErrScopeProjectIDAlone{} - } - if opts.Scope.DomainName != "" { - return nil, ErrScopeProjectIDAlone{} - } - - // ProjectID - return map[string]interface{}{ - "project": map[string]interface{}{ - "id": &opts.Scope.ProjectID, - }, - }, nil - } else if opts.Scope.DomainID != "" { - // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. - if opts.Scope.DomainName != "" { - return nil, ErrScopeDomainIDOrDomainName{} - } - - // DomainID - return map[string]interface{}{ - "domain": map[string]interface{}{ - "id": &opts.Scope.DomainID, - }, - }, nil - } else if opts.Scope.DomainName != "" { - // DomainName - return map[string]interface{}{ - "domain": map[string]interface{}{ - "name": &opts.Scope.DomainName, - }, - }, nil - } - - return nil, nil -} - -func (opts AuthOptions) CanReauth() bool { - if opts.Passcode != "" { - // cannot reauth using TOTP passcode - return false - } - - return opts.AllowReauth -} - -// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder -// interface in the v3 tokens package. -func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) { - return nil, nil -} diff --git a/vendor/github.com/gophercloud/gophercloud/auth_result.go b/vendor/github.com/gophercloud/gophercloud/auth_result.go deleted file mode 100644 index 2e4699b9..00000000 --- a/vendor/github.com/gophercloud/gophercloud/auth_result.go +++ /dev/null @@ -1,52 +0,0 @@ -package gophercloud - -/* -AuthResult is the result from the request that was used to obtain a provider -client's Keystone token. It is returned from ProviderClient.GetAuthResult(). - -The following types satisfy this interface: - - github.com/gophercloud/gophercloud/openstack/identity/v2/tokens.CreateResult - github.com/gophercloud/gophercloud/openstack/identity/v3/tokens.CreateResult - -Usage example: - - import ( - "github.com/gophercloud/gophercloud" - tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens" - tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" - ) - - func GetAuthenticatedUserID(providerClient *gophercloud.ProviderClient) (string, error) { - r := providerClient.GetAuthResult() - if r == nil { - //ProviderClient did not use openstack.Authenticate(), e.g. because token - //was set manually with ProviderClient.SetToken() - return "", errors.New("no AuthResult available") - } - switch r := r.(type) { - case tokens2.CreateResult: - u, err := r.ExtractUser() - if err != nil { - return "", err - } - return u.ID, nil - case tokens3.CreateResult: - u, err := r.ExtractUser() - if err != nil { - return "", err - } - return u.ID, nil - default: - panic(fmt.Sprintf("got unexpected AuthResult type %t", r)) - } - } - -Both implementing types share a lot of methods by name, like ExtractUser() in -this example. But those methods cannot be part of the AuthResult interface -because the return types are different (in this case, type tokens2.User vs. -type tokens3.User). -*/ -type AuthResult interface { - ExtractTokenID() (string, error) -} diff --git a/vendor/github.com/gophercloud/gophercloud/doc.go b/vendor/github.com/gophercloud/gophercloud/doc.go deleted file mode 100644 index 19b64d65..00000000 --- a/vendor/github.com/gophercloud/gophercloud/doc.go +++ /dev/null @@ -1,148 +0,0 @@ -/* -Package gophercloud provides a multi-vendor interface to OpenStack-compatible -clouds. The library has a three-level hierarchy: providers, services, and -resources. - -# Authenticating with Providers - -Provider structs represent the cloud providers that offer and manage a -collection of services. You will generally want to create one Provider -client per OpenStack cloud. - - It is now recommended to use the `clientconfig` package found at - https://github.com/gophercloud/utils/tree/master/openstack/clientconfig - for all authentication purposes. - - The below documentation is still relevant. clientconfig simply implements - the below and presents it in an easier and more flexible way. - -Use your OpenStack credentials to create a Provider client. The -IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in -information provided by the cloud operator. Additionally, the cloud may refer to -TenantID or TenantName as project_id and project_name. Credentials are -specified like so: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - Username: "{username}", - Password: "{password}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(opts) - -You can authenticate with a token by doing: - - opts := gophercloud.AuthOptions{ - IdentityEndpoint: "https://openstack.example.com:5000/v2.0", - TokenID: "{token_id}", - TenantID: "{tenant_id}", - } - - provider, err := openstack.AuthenticatedClient(opts) - -You may also use the openstack.AuthOptionsFromEnv() helper function. This -function reads in standard environment variables frequently found in an -OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant" -instead of "project". - - opts, err := openstack.AuthOptionsFromEnv() - provider, err := openstack.AuthenticatedClient(opts) - -# Service Clients - -Service structs are specific to a provider and handle all of the logic and -operations for a particular OpenStack service. Examples of services include: -Compute, Object Storage, Block Storage. In order to define one, you need to -pass in the parent provider, like so: - - opts := gophercloud.EndpointOpts{Region: "RegionOne"} - - client, err := openstack.NewComputeV2(provider, opts) - -# Resources - -Resource structs are the domain models that services make use of in order -to work with and represent the state of API resources: - - server, err := servers.Get(client, "{serverId}").Extract() - -Intermediate Result structs are returned for API operations, which allow -generic access to the HTTP headers, response body, and any errors associated -with the network transaction. To turn a result into a usable resource struct, -you must call the Extract method which is chained to the response, or an -Extract function from an applicable extension: - - result := servers.Get(client, "{serverId}") - - // Attempt to extract the disk configuration from the OS-DCF disk config - // extension: - config, err := diskconfig.ExtractGet(result) - -All requests that enumerate a collection return a Pager struct that is used to -iterate through the results one page at a time. Use the EachPage method on that -Pager to handle each successive Page in a closure, then use the appropriate -extraction method from that request's package to interpret that Page as a slice -of results: - - err := servers.List(client, nil).EachPage(func (page pagination.Page) (bool, error) { - s, err := servers.ExtractServers(page) - if err != nil { - return false, err - } - - // Handle the []servers.Server slice. - - // Return "false" or an error to prematurely stop fetching new pages. - return true, nil - }) - -If you want to obtain the entire collection of pages without doing any -intermediary processing on each page, you can use the AllPages method: - - allPages, err := servers.List(client, nil).AllPages() - allServers, err := servers.ExtractServers(allPages) - -This top-level package contains utility functions and data types that are used -throughout the provider and service packages. Of particular note for end users -are the AuthOptions and EndpointOpts structs. - -An example retry backoff function, which respects the 429 HTTP response code and a "Retry-After" header: - - endpoint := "http://localhost:5000" - provider, err := openstack.NewClient(endpoint) - if err != nil { - panic(err) - } - provider.MaxBackoffRetries = 3 // max three retries - provider.RetryBackoffFunc = func(ctx context.Context, respErr *ErrUnexpectedResponseCode, e error, retries uint) error { - retryAfter := respErr.ResponseHeader.Get("Retry-After") - if retryAfter == "" { - return e - } - - var sleep time.Duration - - // Parse delay seconds or HTTP date - if v, err := strconv.ParseUint(retryAfter, 10, 32); err == nil { - sleep = time.Duration(v) * time.Second - } else if v, err := time.Parse(http.TimeFormat, retryAfter); err == nil { - sleep = time.Until(v) - } else { - return e - } - - if ctx != nil { - select { - case <-time.After(sleep): - case <-ctx.Done(): - return e - } - } else { - time.Sleep(sleep) - } - - return nil - } -*/ -package gophercloud diff --git a/vendor/github.com/gophercloud/gophercloud/endpoint_search.go b/vendor/github.com/gophercloud/gophercloud/endpoint_search.go deleted file mode 100644 index 2fbc3c97..00000000 --- a/vendor/github.com/gophercloud/gophercloud/endpoint_search.go +++ /dev/null @@ -1,76 +0,0 @@ -package gophercloud - -// Availability indicates to whom a specific service endpoint is accessible: -// the internet at large, internal networks only, or only to administrators. -// Different identity services use different terminology for these. Identity v2 -// lists them as different kinds of URLs within the service catalog ("adminURL", -// "internalURL", and "publicURL"), while v3 lists them as "Interfaces" in an -// endpoint's response. -type Availability string - -const ( - // AvailabilityAdmin indicates that an endpoint is only available to - // administrators. - AvailabilityAdmin Availability = "admin" - - // AvailabilityPublic indicates that an endpoint is available to everyone on - // the internet. - AvailabilityPublic Availability = "public" - - // AvailabilityInternal indicates that an endpoint is only available within - // the cluster's internal network. - AvailabilityInternal Availability = "internal" -) - -// EndpointOpts specifies search criteria used by queries against an -// OpenStack service catalog. The options must contain enough information to -// unambiguously identify one, and only one, endpoint within the catalog. -// -// Usually, these are passed to service client factory functions in a provider -// package, like "openstack.NewComputeV2()". -type EndpointOpts struct { - // Type [required] is the service type for the client (e.g., "compute", - // "object-store"). Generally, this will be supplied by the service client - // function, but a user-given value will be honored if provided. - Type string - - // Name [optional] is the service name for the client (e.g., "nova") as it - // appears in the service catalog. Services can have the same Type but a - // different Name, which is why both Type and Name are sometimes needed. - Name string - - // Region [required] is the geographic region in which the endpoint resides, - // generally specifying which datacenter should house your resources. - // Required only for services that span multiple regions. - Region string - - // Availability [optional] is the visibility of the endpoint to be returned. - // Valid types include the constants AvailabilityPublic, AvailabilityInternal, - // or AvailabilityAdmin from this package. - // - // Availability is not required, and defaults to AvailabilityPublic. Not all - // providers or services offer all Availability options. - Availability Availability -} - -/* -EndpointLocator is an internal function to be used by provider implementations. - -It provides an implementation that locates a single endpoint from a service -catalog for a specific ProviderClient based on user-provided EndpointOpts. The -provider then uses it to discover related ServiceClients. -*/ -type EndpointLocator func(EndpointOpts) (string, error) - -// ApplyDefaults is an internal method to be used by provider implementations. -// -// It sets EndpointOpts fields if not already set, including a default type. -// Currently, EndpointOpts.Availability defaults to the public endpoint. -func (eo *EndpointOpts) ApplyDefaults(t string) { - if eo.Type == "" { - eo.Type = t - } - if eo.Availability == "" { - eo.Availability = AvailabilityPublic - } -} diff --git a/vendor/github.com/gophercloud/gophercloud/errors.go b/vendor/github.com/gophercloud/gophercloud/errors.go deleted file mode 100644 index 8ab592ca..00000000 --- a/vendor/github.com/gophercloud/gophercloud/errors.go +++ /dev/null @@ -1,571 +0,0 @@ -package gophercloud - -import ( - "fmt" - "net/http" - "strings" -) - -// BaseError is an error type that all other error types embed. -type BaseError struct { - DefaultErrString string - Info string -} - -func (e BaseError) Error() string { - e.DefaultErrString = "An error occurred while executing a Gophercloud request." - return e.choseErrString() -} - -func (e BaseError) choseErrString() string { - if e.Info != "" { - return e.Info - } - return e.DefaultErrString -} - -// ErrMissingInput is the error when input is required in a particular -// situation but not provided by the user -type ErrMissingInput struct { - BaseError - Argument string -} - -func (e ErrMissingInput) Error() string { - e.DefaultErrString = fmt.Sprintf("Missing input for argument [%s]", e.Argument) - return e.choseErrString() -} - -// ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors. -type ErrInvalidInput struct { - ErrMissingInput - Value interface{} -} - -func (e ErrInvalidInput) Error() string { - e.DefaultErrString = fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value) - return e.choseErrString() -} - -// ErrMissingEnvironmentVariable is the error when environment variable is required -// in a particular situation but not provided by the user -type ErrMissingEnvironmentVariable struct { - BaseError - EnvironmentVariable string -} - -func (e ErrMissingEnvironmentVariable) Error() string { - e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable) - return e.choseErrString() -} - -// ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables -// is required in a particular situation but not provided by the user -type ErrMissingAnyoneOfEnvironmentVariables struct { - BaseError - EnvironmentVariables []string -} - -func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Missing one of the following environment variables [%s]", - strings.Join(e.EnvironmentVariables, ", "), - ) - return e.choseErrString() -} - -// ErrUnexpectedResponseCode is returned by the Request method when a response code other than -// those listed in OkCodes is encountered. -type ErrUnexpectedResponseCode struct { - BaseError - URL string - Method string - Expected []int - Actual int - Body []byte - ResponseHeader http.Header -} - -func (e ErrUnexpectedResponseCode) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s", - e.Expected, e.Method, e.URL, e.Actual, e.Body, - ) - return e.choseErrString() -} - -// GetStatusCode returns the actual status code of the error. -func (e ErrUnexpectedResponseCode) GetStatusCode() int { - return e.Actual -} - -// StatusCodeError is a convenience interface to easily allow access to the -// status code field of the various ErrDefault* types. -// -// By using this interface, you only have to make a single type cast of -// the returned error to err.(StatusCodeError) and then call GetStatusCode() -// instead of having a large switch statement checking for each of the -// ErrDefault* types. -type StatusCodeError interface { - Error() string - GetStatusCode() int -} - -// ErrDefault400 is the default error type returned on a 400 HTTP response code. -type ErrDefault400 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault400) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault401 is the default error type returned on a 401 HTTP response code. -type ErrDefault401 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault401) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault403 is the default error type returned on a 403 HTTP response code. -type ErrDefault403 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault403) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault404 is the default error type returned on a 404 HTTP response code. -type ErrDefault404 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault404) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault405 is the default error type returned on a 405 HTTP response code. -type ErrDefault405 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault405) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault408 is the default error type returned on a 408 HTTP response code. -type ErrDefault408 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault408) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault409 is the default error type returned on a 409 HTTP response code. -type ErrDefault409 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault409) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault429 is the default error type returned on a 429 HTTP response code. -type ErrDefault429 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault429) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault500 is the default error type returned on a 500 HTTP response code. -type ErrDefault500 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault500) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault502 is the default error type returned on a 502 HTTP response code. -type ErrDefault502 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault502) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault503 is the default error type returned on a 503 HTTP response code. -type ErrDefault503 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault503) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -// ErrDefault504 is the default error type returned on a 504 HTTP response code. -type ErrDefault504 struct { - ErrUnexpectedResponseCode -} - -func (e ErrDefault504) Unwrap() error { - return e.ErrUnexpectedResponseCode -} - -func (e ErrDefault400) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Bad request with: [%s %s], error message: %s", - e.Method, e.URL, e.Body, - ) - return e.choseErrString() -} -func (e ErrDefault401) Error() string { - return "Authentication failed" -} -func (e ErrDefault403) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Request forbidden: [%s %s], error message: %s", - e.Method, e.URL, e.Body, - ) - return e.choseErrString() -} -func (e ErrDefault404) Error() string { - e.DefaultErrString = fmt.Sprintf( - "Resource not found: [%s %s], error message: %s", - e.Method, e.URL, e.Body, - ) - return e.choseErrString() -} -func (e ErrDefault405) Error() string { - return "Method not allowed" -} -func (e ErrDefault408) Error() string { - return "The server timed out waiting for the request" -} -func (e ErrDefault429) Error() string { - return "Too many requests have been sent in a given amount of time. Pause" + - " requests, wait up to one minute, and try again." -} -func (e ErrDefault500) Error() string { - return "Internal Server Error" -} -func (e ErrDefault502) Error() string { - return "Bad Gateway" -} -func (e ErrDefault503) Error() string { - return "The service is currently unable to handle the request due to a temporary" + - " overloading or maintenance. This is a temporary condition. Try again later." -} -func (e ErrDefault504) Error() string { - return "Gateway Timeout" -} - -// Err400er is the interface resource error types implement to override the error message -// from a 400 error. -type Err400er interface { - Error400(ErrUnexpectedResponseCode) error -} - -// Err401er is the interface resource error types implement to override the error message -// from a 401 error. -type Err401er interface { - Error401(ErrUnexpectedResponseCode) error -} - -// Err403er is the interface resource error types implement to override the error message -// from a 403 error. -type Err403er interface { - Error403(ErrUnexpectedResponseCode) error -} - -// Err404er is the interface resource error types implement to override the error message -// from a 404 error. -type Err404er interface { - Error404(ErrUnexpectedResponseCode) error -} - -// Err405er is the interface resource error types implement to override the error message -// from a 405 error. -type Err405er interface { - Error405(ErrUnexpectedResponseCode) error -} - -// Err408er is the interface resource error types implement to override the error message -// from a 408 error. -type Err408er interface { - Error408(ErrUnexpectedResponseCode) error -} - -// Err409er is the interface resource error types implement to override the error message -// from a 409 error. -type Err409er interface { - Error409(ErrUnexpectedResponseCode) error -} - -// Err429er is the interface resource error types implement to override the error message -// from a 429 error. -type Err429er interface { - Error429(ErrUnexpectedResponseCode) error -} - -// Err500er is the interface resource error types implement to override the error message -// from a 500 error. -type Err500er interface { - Error500(ErrUnexpectedResponseCode) error -} - -// Err502er is the interface resource error types implement to override the error message -// from a 502 error. -type Err502er interface { - Error502(ErrUnexpectedResponseCode) error -} - -// Err503er is the interface resource error types implement to override the error message -// from a 503 error. -type Err503er interface { - Error503(ErrUnexpectedResponseCode) error -} - -// Err504er is the interface resource error types implement to override the error message -// from a 504 error. -type Err504er interface { - Error504(ErrUnexpectedResponseCode) error -} - -// ErrTimeOut is the error type returned when an operations times out. -type ErrTimeOut struct { - BaseError -} - -func (e ErrTimeOut) Error() string { - e.DefaultErrString = "A time out occurred" - return e.choseErrString() -} - -// ErrUnableToReauthenticate is the error type returned when reauthentication fails. -type ErrUnableToReauthenticate struct { - BaseError - ErrOriginal error - ErrReauth error -} - -func (e ErrUnableToReauthenticate) Error() string { - e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s: %s", e.ErrOriginal, e.ErrReauth) - return e.choseErrString() -} - -// ErrErrorAfterReauthentication is the error type returned when reauthentication -// succeeds, but an error occurs afterword (usually an HTTP error). -type ErrErrorAfterReauthentication struct { - BaseError - ErrOriginal error -} - -func (e ErrErrorAfterReauthentication) Error() string { - e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal) - return e.choseErrString() -} - -// ErrServiceNotFound is returned when no service in a service catalog matches -// the provided EndpointOpts. This is generally returned by provider service -// factory methods like "NewComputeV2()" and can mean that a service is not -// enabled for your account. -type ErrServiceNotFound struct { - BaseError -} - -func (e ErrServiceNotFound) Error() string { - e.DefaultErrString = "No suitable service could be found in the service catalog." - return e.choseErrString() -} - -// ErrEndpointNotFound is returned when no available endpoints match the -// provided EndpointOpts. This is also generally returned by provider service -// factory methods, and usually indicates that a region was specified -// incorrectly. -type ErrEndpointNotFound struct { - BaseError -} - -func (e ErrEndpointNotFound) Error() string { - e.DefaultErrString = "No suitable endpoint could be found in the service catalog." - return e.choseErrString() -} - -// ErrResourceNotFound is the error when trying to retrieve a resource's -// ID by name and the resource doesn't exist. -type ErrResourceNotFound struct { - BaseError - Name string - ResourceType string -} - -func (e ErrResourceNotFound) Error() string { - e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name) - return e.choseErrString() -} - -// ErrMultipleResourcesFound is the error when trying to retrieve a resource's -// ID by name and multiple resources have the user-provided name. -type ErrMultipleResourcesFound struct { - BaseError - Name string - Count int - ResourceType string -} - -func (e ErrMultipleResourcesFound) Error() string { - e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name) - return e.choseErrString() -} - -// ErrUnexpectedType is the error when an unexpected type is encountered -type ErrUnexpectedType struct { - BaseError - Expected string - Actual string -} - -func (e ErrUnexpectedType) Error() string { - e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual) - return e.choseErrString() -} - -func unacceptedAttributeErr(attribute string) string { - return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute) -} - -func redundantWithTokenErr(attribute string) string { - return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute) -} - -func redundantWithUserID(attribute string) string { - return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute) -} - -// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used. -type ErrAPIKeyProvided struct{ BaseError } - -func (e ErrAPIKeyProvided) Error() string { - return unacceptedAttributeErr("APIKey") -} - -// ErrTenantIDProvided indicates that a TenantID was provided but can't be used. -type ErrTenantIDProvided struct{ BaseError } - -func (e ErrTenantIDProvided) Error() string { - return unacceptedAttributeErr("TenantID") -} - -// ErrTenantNameProvided indicates that a TenantName was provided but can't be used. -type ErrTenantNameProvided struct{ BaseError } - -func (e ErrTenantNameProvided) Error() string { - return unacceptedAttributeErr("TenantName") -} - -// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead. -type ErrUsernameWithToken struct{ BaseError } - -func (e ErrUsernameWithToken) Error() string { - return redundantWithTokenErr("Username") -} - -// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead. -type ErrUserIDWithToken struct{ BaseError } - -func (e ErrUserIDWithToken) Error() string { - return redundantWithTokenErr("UserID") -} - -// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead. -type ErrDomainIDWithToken struct{ BaseError } - -func (e ErrDomainIDWithToken) Error() string { - return redundantWithTokenErr("DomainID") -} - -// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s -type ErrDomainNameWithToken struct{ BaseError } - -func (e ErrDomainNameWithToken) Error() string { - return redundantWithTokenErr("DomainName") -} - -// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once. -type ErrUsernameOrUserID struct{ BaseError } - -func (e ErrUsernameOrUserID) Error() string { - return "Exactly one of Username and UserID must be provided for password authentication" -} - -// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used. -type ErrDomainIDWithUserID struct{ BaseError } - -func (e ErrDomainIDWithUserID) Error() string { - return redundantWithUserID("DomainID") -} - -// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used. -type ErrDomainNameWithUserID struct{ BaseError } - -func (e ErrDomainNameWithUserID) Error() string { - return redundantWithUserID("DomainName") -} - -// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it. -// It may also indicate that both a DomainID and a DomainName were provided at once. -type ErrDomainIDOrDomainName struct{ BaseError } - -func (e ErrDomainIDOrDomainName) Error() string { - return "You must provide exactly one of DomainID or DomainName to authenticate by Username" -} - -// ErrMissingPassword indicates that no password was provided and no token is available. -type ErrMissingPassword struct{ BaseError } - -func (e ErrMissingPassword) Error() string { - return "You must provide a password to authenticate" -} - -// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present. -type ErrScopeDomainIDOrDomainName struct{ BaseError } - -func (e ErrScopeDomainIDOrDomainName) Error() string { - return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName" -} - -// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope. -type ErrScopeProjectIDOrProjectName struct{ BaseError } - -func (e ErrScopeProjectIDOrProjectName) Error() string { - return "You must provide at most one of ProjectID or ProjectName in a Scope" -} - -// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope. -type ErrScopeProjectIDAlone struct{ BaseError } - -func (e ErrScopeProjectIDAlone) Error() string { - return "ProjectID must be supplied alone in a Scope" -} - -// ErrScopeEmpty indicates that no credentials were provided in a Scope. -type ErrScopeEmpty struct{ BaseError } - -func (e ErrScopeEmpty) Error() string { - return "You must provide either a Project or Domain in a Scope" -} - -// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name -type ErrAppCredMissingSecret struct{ BaseError } - -func (e ErrAppCredMissingSecret) Error() string { - return "You must provide an Application Credential Secret" -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/doc.go deleted file mode 100644 index fb20e2ef..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/doc.go +++ /dev/null @@ -1,139 +0,0 @@ -/* -Package routers enables management and retrieval of Routers from the OpenStack -Networking service. - -Example to List Routers - - listOpts := routers.ListOpts{} - allPages, err := routers.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allRouters, err := routers.ExtractRouters(allPages) - if err != nil { - panic(err) - } - - for _, router := range allRoutes { - fmt.Printf("%+v\n", router) - } - -Example to Create a Router - - iTrue := true - gwi := routers.GatewayInfo{ - NetworkID: "8ca37218-28ff-41cb-9b10-039601ea7e6b", - } - - createOpts := routers.CreateOpts{ - Name: "router_1", - AdminStateUp: &iTrue, - GatewayInfo: &gwi, - } - - router, err := routers.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - routes := []routers.Route{{ - DestinationCIDR: "40.0.1.0/24", - NextHop: "10.1.0.10", - }} - - updateOpts := routers.UpdateOpts{ - Name: "new_name", - Routes: &routes, - } - - router, err := routers.Update(networkClient, routerID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update just the Router name, keeping everything else as-is - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - updateOpts := routers.UpdateOpts{ - Name: "new_name", - } - - router, err := routers.Update(networkClient, routerID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Remove all Routes from a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - routes := []routers.Route{} - - updateOpts := routers.UpdateOpts{ - Routes: &routes, - } - - router, err := routers.Update(networkClient, routerID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - err := routers.Delete(networkClient, routerID).ExtractErr() - if err != nil { - panic(err) - } - -Example to Add an Interface to a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - intOpts := routers.AddInterfaceOpts{ - SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1", - } - - interface, err := routers.AddInterface(networkClient, routerID, intOpts).Extract() - if err != nil { - panic(err) - } - -Example to Remove an Interface from a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - intOpts := routers.RemoveInterfaceOpts{ - SubnetID: "a2f1f29d-571b-4533-907f-5803ab96ead1", - } - - interface, err := routers.RemoveInterface(networkClient, routerID, intOpts).Extract() - if err != nil { - panic(err) - } - -Example to List an L3 agents for a Router - - routerID := "4e8e5957-649f-477b-9e5b-f1f75b21c03c" - - allPages, err := routers.ListL3Agents(networkClient, routerID).AllPages() - if err != nil { - panic(err) - } - - allL3Agents, err := routers.ExtractL3Agents(allPages) - if err != nil { - panic(err) - } - - for _, agent := range allL3Agents { - fmt.Printf("%+v\n", agent) - } -*/ -package routers diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go deleted file mode 100644 index 81665ace..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/requests.go +++ /dev/null @@ -1,246 +0,0 @@ -package routers - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the floating IP attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - Description string `q:"description"` - AdminStateUp *bool `q:"admin_state_up"` - Distributed *bool `q:"distributed"` - Status string `q:"status"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` -} - -// List returns a Pager which allows you to iterate over a collection of -// routers. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those routers that are owned by the -// tenant who submits the request, unless an admin user submits the request. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return RouterPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToRouterCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains all the values needed to create a new router. There are -// no required values. -type CreateOpts struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Distributed *bool `json:"distributed,omitempty"` - TenantID string `json:"tenant_id,omitempty"` - ProjectID string `json:"project_id,omitempty"` - GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` - AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"` -} - -// ToRouterCreateMap builds a create request body from CreateOpts. -func (opts CreateOpts) ToRouterCreateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "router") -} - -// Create accepts a CreateOpts struct and uses the values to create a new -// logical router. When it is created, the router does not have an internal -// interface - it is not associated to any subnet. -// -// You can optionally specify an external gateway for a router using the -// GatewayInfo struct. The external gateway for the router must be plugged into -// an external network (it is external if its `router:external' field is set to -// true). -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToRouterCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Post(rootURL(c), b, &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Get retrieves a particular router based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { - resp, err := c.Get(resourceURL(c, id), &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToRouterUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contains the values used when updating a router. -type UpdateOpts struct { - Name string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Distributed *bool `json:"distributed,omitempty"` - GatewayInfo *GatewayInfo `json:"external_gateway_info,omitempty"` - Routes *[]Route `json:"routes,omitempty"` -} - -// ToRouterUpdateMap builds an update body based on UpdateOpts. -func (opts UpdateOpts) ToRouterUpdateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "router") -} - -// Update allows routers to be updated. You can update the name, administrative -// state, and the external gateway. For more information about how to set the -// external gateway for a router, see Create. This operation does not enable -// the update of router interfaces. To do this, use the AddInterface and -// RemoveInterface functions. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToRouterUpdateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Delete will permanently delete a particular router based on its unique ID. -func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { - resp, err := c.Delete(resourceURL(c, id), nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// AddInterfaceOptsBuilder allows extensions to add additional parameters to -// the AddInterface request. -type AddInterfaceOptsBuilder interface { - ToRouterAddInterfaceMap() (map[string]interface{}, error) -} - -// AddInterfaceOpts represents the options for adding an interface to a router. -type AddInterfaceOpts struct { - SubnetID string `json:"subnet_id,omitempty" xor:"PortID"` - PortID string `json:"port_id,omitempty" xor:"SubnetID"` -} - -// ToRouterAddInterfaceMap builds a request body from AddInterfaceOpts. -func (opts AddInterfaceOpts) ToRouterAddInterfaceMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "") -} - -// AddInterface attaches a subnet to an internal router interface. You must -// specify either a SubnetID or PortID in the request body. If you specify both, -// the operation will fail and an error will be returned. -// -// If you specify a SubnetID, the gateway IP address for that particular subnet -// is used to create the router interface. Alternatively, if you specify a -// PortID, the IP address associated with the port is used to create the router -// interface. -// -// If you reference a port that is associated with multiple IP addresses, or -// if the port is associated with zero IP addresses, the operation will fail and -// a 400 Bad Request error will be returned. -// -// If you reference a port already in use, the operation will fail and a 409 -// Conflict error will be returned. -// -// The PortID that is returned after using Extract() on the result of this -// operation can either be the same PortID passed in or, on the other hand, the -// identifier of a new port created by this operation. After the operation -// completes, the device ID of the port is set to the router ID, and the -// device owner attribute is set to `network:router_interface'. -func AddInterface(c *gophercloud.ServiceClient, id string, opts AddInterfaceOptsBuilder) (r InterfaceResult) { - b, err := opts.ToRouterAddInterfaceMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Put(addInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// RemoveInterfaceOptsBuilder allows extensions to add additional parameters to -// the RemoveInterface request. -type RemoveInterfaceOptsBuilder interface { - ToRouterRemoveInterfaceMap() (map[string]interface{}, error) -} - -// RemoveInterfaceOpts represents options for removing an interface from -// a router. -type RemoveInterfaceOpts struct { - SubnetID string `json:"subnet_id,omitempty" or:"PortID"` - PortID string `json:"port_id,omitempty" or:"SubnetID"` -} - -// ToRouterRemoveInterfaceMap builds a request body based on -// RemoveInterfaceOpts. -func (opts RemoveInterfaceOpts) ToRouterRemoveInterfaceMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "") -} - -// RemoveInterface removes an internal router interface, which detaches a -// subnet from the router. You must specify either a SubnetID or PortID, since -// these values are used to identify the router interface to remove. -// -// Unlike AddInterface, you can also specify both a SubnetID and PortID. If you -// choose to specify both, the subnet ID must correspond to the subnet ID of -// the first IP address on the port specified by the port ID. Otherwise, the -// operation will fail and return a 409 Conflict error. -// -// If the router, subnet or port which are referenced do not exist or are not -// visible to you, the operation will fail and a 404 Not Found error will be -// returned. After this operation completes, the port connecting the router -// with the subnet is removed from the subnet for the network. -func RemoveInterface(c *gophercloud.ServiceClient, id string, opts RemoveInterfaceOptsBuilder) (r InterfaceResult) { - b, err := opts.ToRouterRemoveInterfaceMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Put(removeInterfaceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// ListL3Agents returns a list of l3-agents scheduled for a specific router. -func ListL3Agents(c *gophercloud.ServiceClient, id string) (result pagination.Pager) { - return pagination.NewPager(c, listl3AgentsURL(c, id), func(r pagination.PageResult) pagination.Page { - return ListL3AgentsPage{pagination.SinglePageBase(r)} - }) -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go deleted file mode 100644 index 0c939189..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/results.go +++ /dev/null @@ -1,285 +0,0 @@ -package routers - -import ( - "encoding/json" - "time" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// GatewayInfo represents the information of an external gateway for any -// particular network router. -type GatewayInfo struct { - NetworkID string `json:"network_id,omitempty"` - EnableSNAT *bool `json:"enable_snat,omitempty"` - ExternalFixedIPs []ExternalFixedIP `json:"external_fixed_ips,omitempty"` -} - -// ExternalFixedIP is the IP address and subnet ID of the external gateway of a -// router. -type ExternalFixedIP struct { - IPAddress string `json:"ip_address,omitempty"` - SubnetID string `json:"subnet_id"` -} - -// Route is a possible route in a router. -type Route struct { - NextHop string `json:"nexthop"` - DestinationCIDR string `json:"destination"` -} - -// Router represents a Neutron router. A router is a logical entity that -// forwards packets across internal subnets and NATs (network address -// translation) them on external networks through an appropriate gateway. -// -// A router has an interface for each subnet with which it is associated. By -// default, the IP address of such interface is the subnet's gateway IP. Also, -// whenever a router is associated with a subnet, a port for that router -// interface is added to the subnet's network. -type Router struct { - // Status indicates whether or not a router is currently operational. - Status string `json:"status"` - - // GateayInfo provides information on external gateway for the router. - GatewayInfo GatewayInfo `json:"external_gateway_info"` - - // AdminStateUp is the administrative state of the router. - AdminStateUp bool `json:"admin_state_up"` - - // Distributed is whether router is disitrubted or not. - Distributed bool `json:"distributed"` - - // Name is the human readable name for the router. It does not have to be - // unique. - Name string `json:"name"` - - // Description for the router. - Description string `json:"description"` - - // ID is the unique identifier for the router. - ID string `json:"id"` - - // TenantID is the project owner of the router. Only admin users can - // specify a project identifier other than its own. - TenantID string `json:"tenant_id"` - - // ProjectID is the project owner of the router. - ProjectID string `json:"project_id"` - - // Routes are a collection of static routes that the router will host. - Routes []Route `json:"routes"` - - // Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others. - // Used to make network resources highly available. - AvailabilityZoneHints []string `json:"availability_zone_hints"` - - // Tags optionally set via extensions/attributestags - Tags []string `json:"tags"` -} - -// RouterPage is the page returned by a pager when traversing over a -// collection of routers. -type RouterPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of routers has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r RouterPage) NextPageURL() (string, error) { - var s struct { - Links []gophercloud.Link `json:"routers_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return gophercloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a RouterPage struct is empty. -func (r RouterPage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - is, err := ExtractRouters(r) - return len(is) == 0, err -} - -// ExtractRouters accepts a Page struct, specifically a RouterPage struct, -// and extracts the elements into a slice of Router structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractRouters(r pagination.Page) ([]Router, error) { - var s struct { - Routers []Router `json:"routers"` - } - err := (r.(RouterPage)).ExtractInto(&s) - return s.Routers, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a router. -func (r commonResult) Extract() (*Router, error) { - var s struct { - Router *Router `json:"router"` - } - err := r.ExtractInto(&s) - return s.Router, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Router. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Router. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Router. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its ExtractErr -// method to determine if the request succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} - -// InterfaceInfo represents information about a particular router interface. As -// mentioned above, in order for a router to forward to a subnet, it needs an -// interface. -type InterfaceInfo struct { - // SubnetID is the ID of the subnet which this interface is associated with. - SubnetID string `json:"subnet_id"` - - // PortID is the ID of the port that is a part of the subnet. - PortID string `json:"port_id"` - - // ID is the UUID of the interface. - ID string `json:"id"` - - // TenantID is the owner of the interface. - TenantID string `json:"tenant_id"` -} - -// InterfaceResult represents the result of interface operations, such as -// AddInterface() and RemoveInterface(). Call its Extract method to interpret -// the result as a InterfaceInfo. -type InterfaceResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts an information struct. -func (r InterfaceResult) Extract() (*InterfaceInfo, error) { - var s InterfaceInfo - err := r.ExtractInto(&s) - return &s, err -} - -// L3Agent represents a Neutron agent for routers. -type L3Agent struct { - // ID is the id of the agent. - ID string `json:"id"` - - // AdminStateUp is an administrative state of the agent. - AdminStateUp bool `json:"admin_state_up"` - - // AgentType is a type of the agent. - AgentType string `json:"agent_type"` - - // Alive indicates whether agent is alive or not. - Alive bool `json:"alive"` - - // ResourcesSynced indicates whether agent is synced or not. - // Not all agent types track resources via Placement. - ResourcesSynced bool `json:"resources_synced"` - - // AvailabilityZone is a zone of the agent. - AvailabilityZone string `json:"availability_zone"` - - // Binary is an executable binary of the agent. - Binary string `json:"binary"` - - // Configurations is a configuration specific key/value pairs that are - // determined by the agent binary and type. - Configurations map[string]interface{} `json:"configurations"` - - // CreatedAt is a creation timestamp. - CreatedAt time.Time `json:"-"` - - // StartedAt is a starting timestamp. - StartedAt time.Time `json:"-"` - - // HeartbeatTimestamp is a last heartbeat timestamp. - HeartbeatTimestamp time.Time `json:"-"` - - // Description contains agent description. - Description string `json:"description"` - - // Host is a hostname of the agent system. - Host string `json:"host"` - - // Topic contains name of AMQP topic. - Topic string `json:"topic"` - - // HAState is a ha state of agent(active/standby) for router - HAState string `json:"ha_state"` - - // ResourceVersions is a list agent known objects and version numbers - ResourceVersions map[string]interface{} `json:"resource_versions"` -} - -// UnmarshalJSON helps to convert the timestamps into the time.Time type. -func (r *L3Agent) UnmarshalJSON(b []byte) error { - type tmp L3Agent - var s struct { - tmp - CreatedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"created_at"` - StartedAt gophercloud.JSONRFC3339ZNoTNoZ `json:"started_at"` - HeartbeatTimestamp gophercloud.JSONRFC3339ZNoTNoZ `json:"heartbeat_timestamp"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = L3Agent(s.tmp) - - r.CreatedAt = time.Time(s.CreatedAt) - r.StartedAt = time.Time(s.StartedAt) - r.HeartbeatTimestamp = time.Time(s.HeartbeatTimestamp) - - return nil -} - -type ListL3AgentsPage struct { - pagination.SinglePageBase -} - -func (r ListL3AgentsPage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - v, err := ExtractL3Agents(r) - return len(v) == 0, err -} - -func ExtractL3Agents(r pagination.Page) ([]L3Agent, error) { - var s struct { - L3Agents []L3Agent `json:"agents"` - } - - err := (r.(ListL3AgentsPage)).ExtractInto(&s) - return s.L3Agents, err -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go deleted file mode 100644 index 7b30f903..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers/urls.go +++ /dev/null @@ -1,25 +0,0 @@ -package routers - -import "github.com/gophercloud/gophercloud" - -const resourcePath = "routers" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(resourcePath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id) -} - -func addInterfaceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id, "add_router_interface") -} - -func removeInterfaceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id, "remove_router_interface") -} - -func listl3AgentsURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(resourcePath, id, "l3-agents") -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/doc.go deleted file mode 100644 index 7d8bbcaa..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/doc.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Package groups provides information and interaction with Security Groups -for the OpenStack Networking service. - -Example to List Security Groups - - listOpts := groups.ListOpts{ - TenantID: "966b3c7d36a24facaf20b7e458bf2192", - } - - allPages, err := groups.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allGroups, err := groups.ExtractGroups(allPages) - if err != nil { - panic(err) - } - - for _, group := range allGroups { - fmt.Printf("%+v\n", group) - } - -Example to Create a Security Group - - createOpts := groups.CreateOpts{ - Name: "group_name", - Description: "A Security Group", - } - - group, err := groups.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Security Group - - groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" - - updateOpts := groups.UpdateOpts{ - Name: "new_name", - } - - group, err := groups.Update(networkClient, groupID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Security Group - - groupID := "37d94f8a-d136-465c-ae46-144f0d8ef141" - err := groups.Delete(networkClient, groupID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package groups diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go deleted file mode 100644 index 566a730e..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/requests.go +++ /dev/null @@ -1,133 +0,0 @@ -package groups - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the group attributes you want to see returned. SortKey allows you to -// sort by a particular network attribute. SortDir sets the direction, and is -// either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - ID string `q:"id"` - Name string `q:"name"` - Description string `q:"description"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` -} - -// List returns a Pager which allows you to iterate over a collection of -// security groups. It accepts a ListOpts struct, which allows you to filter -// and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return SecGroupPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToSecGroupCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains all the values needed to create a new security group. -type CreateOpts struct { - // Human-readable name for the Security Group. Does not have to be unique. - Name string `json:"name" required:"true"` - - // TenantID is the UUID of the project who owns the Group. - // Only administrative users can specify a tenant UUID other than their own. - TenantID string `json:"tenant_id,omitempty"` - - // ProjectID is the UUID of the project who owns the Group. - // Only administrative users can specify a tenant UUID other than their own. - ProjectID string `json:"project_id,omitempty"` - - // Describes the security group. - Description string `json:"description,omitempty"` -} - -// ToSecGroupCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToSecGroupCreateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "security_group") -} - -// Create is an operation which provisions a new security group with default -// security group rules for the IPv4 and IPv6 ether types. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToSecGroupCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Post(rootURL(c), b, &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToSecGroupUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts contains all the values needed to update an existing security -// group. -type UpdateOpts struct { - // Human-readable name for the Security Group. Does not have to be unique. - Name string `json:"name,omitempty"` - - // Describes the security group. - Description *string `json:"description,omitempty"` -} - -// ToSecGroupUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToSecGroupUpdateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "security_group") -} - -// Update is an operation which updates an existing security group. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToSecGroupUpdateMap() - if err != nil { - r.Err = err - return - } - - resp, err := c.Put(resourceURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Get retrieves a particular security group based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { - resp, err := c.Get(resourceURL(c, id), &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Delete will permanently delete a particular security group based on its -// unique ID. -func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { - resp, err := c.Delete(resourceURL(c, id), nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go deleted file mode 100644 index 2027037d..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/results.go +++ /dev/null @@ -1,158 +0,0 @@ -package groups - -import ( - "encoding/json" - "time" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules" - "github.com/gophercloud/gophercloud/pagination" -) - -// SecGroup represents a container for security group rules. -type SecGroup struct { - // The UUID for the security group. - ID string - - // Human-readable name for the security group. Might not be unique. - // Cannot be named "default" as that is automatically created for a tenant. - Name string - - // The security group description. - Description string - - // A slice of security group rules that dictate the permitted behaviour for - // traffic entering and leaving the group. - Rules []rules.SecGroupRule `json:"security_group_rules"` - - // TenantID is the project owner of the security group. - TenantID string `json:"tenant_id"` - - // UpdatedAt and CreatedAt contain ISO-8601 timestamps of when the state of the - // security group last changed, and when it was created. - UpdatedAt time.Time `json:"-"` - CreatedAt time.Time `json:"-"` - - // ProjectID is the project owner of the security group. - ProjectID string `json:"project_id"` - - // Tags optionally set via extensions/attributestags - Tags []string `json:"tags"` -} - -func (r *SecGroup) UnmarshalJSON(b []byte) error { - type tmp SecGroup - - // Support for older neutron time format - var s1 struct { - tmp - CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` - UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` - } - - err := json.Unmarshal(b, &s1) - if err == nil { - *r = SecGroup(s1.tmp) - r.CreatedAt = time.Time(s1.CreatedAt) - r.UpdatedAt = time.Time(s1.UpdatedAt) - - return nil - } - - // Support for newer neutron time format - var s2 struct { - tmp - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - } - - err = json.Unmarshal(b, &s2) - if err != nil { - return err - } - - *r = SecGroup(s2.tmp) - r.CreatedAt = time.Time(s2.CreatedAt) - r.UpdatedAt = time.Time(s2.UpdatedAt) - - return nil -} - -// SecGroupPage is the page returned by a pager when traversing over a -// collection of security groups. -type SecGroupPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of security groups has -// reached the end of a page and the pager seeks to traverse over a new one. In -// order to do this, it needs to construct the next page's URL. -func (r SecGroupPage) NextPageURL() (string, error) { - var s struct { - Links []gophercloud.Link `json:"security_groups_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - - return gophercloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a SecGroupPage struct is empty. -func (r SecGroupPage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - is, err := ExtractGroups(r) - return len(is) == 0, err -} - -// ExtractGroups accepts a Page struct, specifically a SecGroupPage struct, -// and extracts the elements into a slice of SecGroup structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractGroups(r pagination.Page) ([]SecGroup, error) { - var s struct { - SecGroups []SecGroup `json:"security_groups"` - } - err := (r.(SecGroupPage)).ExtractInto(&s) - return s.SecGroups, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a security group. -func (r commonResult) Extract() (*SecGroup, error) { - var s struct { - SecGroup *SecGroup `json:"security_group"` - } - err := r.ExtractInto(&s) - return s.SecGroup, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a SecGroup. -type CreateResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a SecGroup. -type UpdateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a SecGroup. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go deleted file mode 100644 index 104cbcc5..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package groups - -import "github.com/gophercloud/gophercloud" - -const rootPath = "security-groups" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, id) -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/doc.go deleted file mode 100644 index bf66dc8b..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/doc.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Package rules provides information and interaction with Security Group Rules -for the OpenStack Networking service. - -Example to List Security Groups Rules - - listOpts := rules.ListOpts{ - Protocol: "tcp", - } - - allPages, err := rules.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allRules, err := rules.ExtractRules(allPages) - if err != nil { - panic(err) - } - - for _, rule := range allRules { - fmt.Printf("%+v\n", rule) - } - -Example to Create a Security Group Rule - - createOpts := rules.CreateOpts{ - Direction: "ingress", - PortRangeMin: 80, - EtherType: rules.EtherType4, - PortRangeMax: 80, - Protocol: "tcp", - RemoteGroupID: "85cc3048-abc3-43cc-89b3-377341426ac5", - SecGroupID: "a7734e61-b545-452d-a3cd-0189cbd9747a", - } - - rule, err := rules.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Security Group Rule - - ruleID := "37d94f8a-d136-465c-ae46-144f0d8ef141" - err := rules.Delete(networkClient, ruleID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package rules diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go deleted file mode 100644 index 364f7f5c..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/requests.go +++ /dev/null @@ -1,164 +0,0 @@ -package rules - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the security group rule attributes you want to see returned. SortKey allows -// you to sort by a particular network attribute. SortDir sets the direction, -// and is either `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Direction string `q:"direction"` - EtherType string `q:"ethertype"` - ID string `q:"id"` - Description string `q:"description"` - PortRangeMax int `q:"port_range_max"` - PortRangeMin int `q:"port_range_min"` - Protocol string `q:"protocol"` - RemoteGroupID string `q:"remote_group_id"` - RemoteIPPrefix string `q:"remote_ip_prefix"` - SecGroupID string `q:"security_group_id"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` -} - -// List returns a Pager which allows you to iterate over a collection of -// security group rules. It accepts a ListOpts struct, which allows you to filter -// and sort the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager { - q, err := gophercloud.BuildQueryString(&opts) - if err != nil { - return pagination.Pager{Err: err} - } - u := rootURL(c) + q.String() - return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page { - return SecGroupRulePage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -type RuleDirection string -type RuleProtocol string -type RuleEtherType string - -// Constants useful for CreateOpts -const ( - DirIngress RuleDirection = "ingress" - DirEgress RuleDirection = "egress" - EtherType4 RuleEtherType = "IPv4" - EtherType6 RuleEtherType = "IPv6" - ProtocolAH RuleProtocol = "ah" - ProtocolDCCP RuleProtocol = "dccp" - ProtocolEGP RuleProtocol = "egp" - ProtocolESP RuleProtocol = "esp" - ProtocolGRE RuleProtocol = "gre" - ProtocolICMP RuleProtocol = "icmp" - ProtocolIGMP RuleProtocol = "igmp" - ProtocolIPIP RuleProtocol = "ipip" - ProtocolIPv6Encap RuleProtocol = "ipv6-encap" - ProtocolIPv6Frag RuleProtocol = "ipv6-frag" - ProtocolIPv6ICMP RuleProtocol = "ipv6-icmp" - ProtocolIPv6NoNxt RuleProtocol = "ipv6-nonxt" - ProtocolIPv6Opts RuleProtocol = "ipv6-opts" - ProtocolIPv6Route RuleProtocol = "ipv6-route" - ProtocolOSPF RuleProtocol = "ospf" - ProtocolPGM RuleProtocol = "pgm" - ProtocolRSVP RuleProtocol = "rsvp" - ProtocolSCTP RuleProtocol = "sctp" - ProtocolTCP RuleProtocol = "tcp" - ProtocolUDP RuleProtocol = "udp" - ProtocolUDPLite RuleProtocol = "udplite" - ProtocolVRRP RuleProtocol = "vrrp" - ProtocolAny RuleProtocol = "any" -) - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToSecGroupRuleCreateMap() (map[string]interface{}, error) -} - -// CreateOpts contains all the values needed to create a new security group -// rule. -type CreateOpts struct { - // Must be either "ingress" or "egress": the direction in which the security - // group rule is applied. - Direction RuleDirection `json:"direction" required:"true"` - - // String description of each rule, optional - Description string `json:"description,omitempty"` - - // Must be "IPv4" or "IPv6", and addresses represented in CIDR must match the - // ingress or egress rules. - EtherType RuleEtherType `json:"ethertype" required:"true"` - - // The security group ID to associate with this security group rule. - SecGroupID string `json:"security_group_id" required:"true"` - - // The maximum port number in the range that is matched by the security group - // rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If - // the protocol is ICMP, this value must be an ICMP type. - PortRangeMax int `json:"port_range_max,omitempty"` - - // The minimum port number in the range that is matched by the security group - // rule. If the protocol is TCP or UDP, this value must be less than or equal - // to the value of the PortRangeMax attribute. If the protocol is ICMP, this - // value must be an ICMP type. - PortRangeMin int `json:"port_range_min,omitempty"` - - // The protocol that is matched by the security group rule. Valid values are - // "tcp", "udp", "icmp" or an empty string. - Protocol RuleProtocol `json:"protocol,omitempty"` - - // The remote group ID to be associated with this security group rule. You can - // specify either RemoteGroupID or RemoteIPPrefix. - RemoteGroupID string `json:"remote_group_id,omitempty"` - - // The remote IP prefix to be associated with this security group rule. You can - // specify either RemoteGroupID or RemoteIPPrefix. This attribute matches the - // specified IP prefix as the source IP address of the IP packet. - RemoteIPPrefix string `json:"remote_ip_prefix,omitempty"` - - // TenantID is the UUID of the project who owns the Rule. - // Only administrative users can specify a project UUID other than their own. - ProjectID string `json:"project_id,omitempty"` -} - -// ToSecGroupRuleCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToSecGroupRuleCreateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "security_group_rule") -} - -// Create is an operation which adds a new security group rule and associates it -// with an existing security group (whose ID is specified in CreateOpts). -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToSecGroupRuleCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Post(rootURL(c), b, &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Get retrieves a particular security group rule based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { - resp, err := c.Get(resourceURL(c, id), &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Delete will permanently delete a particular security group rule based on its -// unique ID. -func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { - resp, err := c.Delete(resourceURL(c, id), nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go deleted file mode 100644 index 1e65f062..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/results.go +++ /dev/null @@ -1,131 +0,0 @@ -package rules - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// SecGroupRule represents a rule to dictate the behaviour of incoming or -// outgoing traffic for a particular security group. -type SecGroupRule struct { - // The UUID for this security group rule. - ID string - - // The direction in which the security group rule is applied. The only values - // allowed are "ingress" or "egress". For a compute instance, an ingress - // security group rule is applied to incoming (ingress) traffic for that - // instance. An egress rule is applied to traffic leaving the instance. - Direction string - - // Description of the rule - Description string `json:"description"` - - // Must be IPv4 or IPv6, and addresses represented in CIDR must match the - // ingress or egress rules. - EtherType string `json:"ethertype"` - - // The security group ID to associate with this security group rule. - SecGroupID string `json:"security_group_id"` - - // The minimum port number in the range that is matched by the security group - // rule. If the protocol is TCP or UDP, this value must be less than or equal - // to the value of the PortRangeMax attribute. If the protocol is ICMP, this - // value must be an ICMP type. - PortRangeMin int `json:"port_range_min"` - - // The maximum port number in the range that is matched by the security group - // rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If - // the protocol is ICMP, this value must be an ICMP type. - PortRangeMax int `json:"port_range_max"` - - // The protocol that is matched by the security group rule. Valid values are - // "tcp", "udp", "icmp" or an empty string. - Protocol string - - // The remote group ID to be associated with this security group rule. You - // can specify either RemoteGroupID or RemoteIPPrefix. - RemoteGroupID string `json:"remote_group_id"` - - // The remote IP prefix to be associated with this security group rule. You - // can specify either RemoteGroupID or RemoteIPPrefix . This attribute - // matches the specified IP prefix as the source IP address of the IP packet. - RemoteIPPrefix string `json:"remote_ip_prefix"` - - // TenantID is the project owner of this security group rule. - TenantID string `json:"tenant_id"` - - // ProjectID is the project owner of this security group rule. - ProjectID string `json:"project_id"` -} - -// SecGroupRulePage is the page returned by a pager when traversing over a -// collection of security group rules. -type SecGroupRulePage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of security group rules has -// reached the end of a page and the pager seeks to traverse over a new one. In -// order to do this, it needs to construct the next page's URL. -func (r SecGroupRulePage) NextPageURL() (string, error) { - var s struct { - Links []gophercloud.Link `json:"security_group_rules_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return gophercloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a SecGroupRulePage struct is empty. -func (r SecGroupRulePage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - is, err := ExtractRules(r) - return len(is) == 0, err -} - -// ExtractRules accepts a Page struct, specifically a SecGroupRulePage struct, -// and extracts the elements into a slice of SecGroupRule structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractRules(r pagination.Page) ([]SecGroupRule, error) { - var s struct { - SecGroupRules []SecGroupRule `json:"security_group_rules"` - } - err := (r.(SecGroupRulePage)).ExtractInto(&s) - return s.SecGroupRules, err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a security rule. -func (r commonResult) Extract() (*SecGroupRule, error) { - var s struct { - SecGroupRule *SecGroupRule `json:"security_group_rule"` - } - err := r.ExtractInto(&s) - return s.SecGroupRule, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a SecGroupRule. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a SecGroupRule. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go deleted file mode 100644 index a5ede0e8..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules/urls.go +++ /dev/null @@ -1,13 +0,0 @@ -package rules - -import "github.com/gophercloud/gophercloud" - -const rootPath = "security-group-rules" - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL(rootPath) -} - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL(rootPath, id) -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go deleted file mode 100644 index 9d1dd5a7..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -/* -Package networks contains functionality for working with Neutron network -resources. A network is an isolated virtual layer-2 broadcast domain that is -typically reserved for the tenant who created it (unless you configure the -network to be shared). Tenants can create multiple networks until the -thresholds per-tenant quota is reached. - -In the v2.0 Networking API, the network is the main entity. Ports and subnets -are always associated with a network. - -Example to List Networks - - listOpts := networks.ListOpts{ - TenantID: "a99e9b4e620e4db09a2dfb6e42a01e66", - } - - allPages, err := networks.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allNetworks, err := networks.ExtractNetworks(allPages) - if err != nil { - panic(err) - } - - for _, network := range allNetworks { - fmt.Printf("%+v", network) - } - -Example to Create a Network - - iTrue := true - createOpts := networks.CreateOpts{ - Name: "network_1", - AdminStateUp: &iTrue, - } - - network, err := networks.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Network - - networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - - name := "new_name" - updateOpts := networks.UpdateOpts{ - Name: &name, - } - - network, err := networks.Update(networkClient, networkID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Network - - networkID := "484cda0e-106f-4f4b-bb3f-d413710bbe78" - err := networks.Delete(networkClient, networkID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package networks diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go deleted file mode 100644 index 00c2eae7..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/requests.go +++ /dev/null @@ -1,165 +0,0 @@ -package networks - -import ( - "fmt" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToNetworkListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the network attributes you want to see returned. SortKey allows you to sort -// by a particular network attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Status string `q:"status"` - Name string `q:"name"` - Description string `q:"description"` - AdminStateUp *bool `q:"admin_state_up"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - Shared *bool `q:"shared"` - ID string `q:"id"` - Marker string `q:"marker"` - Limit int `q:"limit"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` -} - -// ToNetworkListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToNetworkListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// networks. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToNetworkListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return NetworkPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific network based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { - resp, err := c.Get(getURL(c, id), &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// Create request. -type CreateOptsBuilder interface { - ToNetworkCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents options used to create a network. -type CreateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Shared *bool `json:"shared,omitempty"` - TenantID string `json:"tenant_id,omitempty"` - ProjectID string `json:"project_id,omitempty"` - AvailabilityZoneHints []string `json:"availability_zone_hints,omitempty"` -} - -// ToNetworkCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToNetworkCreateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "network") -} - -// Create accepts a CreateOpts struct and creates a new network using the values -// provided. This operation does not actually require a request body, i.e. the -// CreateOpts struct argument can be empty. -// -// The tenant ID that is contained in the URI is the tenant that creates the -// network. An admin user, however, has the option of specifying another tenant -// ID in the CreateOpts struct. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToNetworkCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Post(createURL(c), b, &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToNetworkUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents options used to update a network. -type UpdateOpts struct { - AdminStateUp *bool `json:"admin_state_up,omitempty"` - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Shared *bool `json:"shared,omitempty"` - - // RevisionNumber implements extension:standard-attr-revisions. If != "" it - // will set revision_number=%s. If the revision number does not match, the - // update will fail. - RevisionNumber *int `json:"-" h:"If-Match"` -} - -// ToNetworkUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToNetworkUpdateMap() (map[string]interface{}, error) { - return gophercloud.BuildRequestBody(opts, "network") -} - -// Update accepts a UpdateOpts struct and updates an existing network using the -// values provided. For more information, see the Create function. -func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToNetworkUpdateMap() - if err != nil { - r.Err = err - return - } - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - r.Err = err - return - } - for k := range h { - if k == "If-Match" { - h[k] = fmt.Sprintf("revision_number=%s", h[k]) - } - } - resp, err := c.Put(updateURL(c, networkID), b, &r.Body, &gophercloud.RequestOpts{ - MoreHeaders: h, - OkCodes: []int{200, 201}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Delete accepts a unique ID and deletes the network associated with it. -func Delete(c *gophercloud.ServiceClient, networkID string) (r DeleteResult) { - resp, err := c.Delete(deleteURL(c, networkID), nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go deleted file mode 100644 index 2a020a13..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/results.go +++ /dev/null @@ -1,177 +0,0 @@ -package networks - -import ( - "encoding/json" - "time" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a network resource. -func (r commonResult) Extract() (*Network, error) { - var s Network - err := r.ExtractInto(&s) - return &s, err -} - -func (r commonResult) ExtractInto(v interface{}) error { - return r.Result.ExtractIntoStructPtr(v, "network") -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Network. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Network. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Network. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} - -// Network represents, well, a network. -type Network struct { - // UUID for the network - ID string `json:"id"` - - // Human-readable name for the network. Might not be unique. - Name string `json:"name"` - - // Description for the network - Description string `json:"description"` - - // The administrative state of network. If false (down), the network does not - // forward packets. - AdminStateUp bool `json:"admin_state_up"` - - // Indicates whether network is currently operational. Possible values include - // `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional - // values. - Status string `json:"status"` - - // Subnets associated with this network. - Subnets []string `json:"subnets"` - - // TenantID is the project owner of the network. - TenantID string `json:"tenant_id"` - - // UpdatedAt and CreatedAt contain ISO-8601 timestamps of when the state of the - // network last changed, and when it was created. - UpdatedAt time.Time `json:"-"` - CreatedAt time.Time `json:"-"` - - // ProjectID is the project owner of the network. - ProjectID string `json:"project_id"` - - // Specifies whether the network resource can be accessed by any tenant. - Shared bool `json:"shared"` - - // Availability zone hints groups network nodes that run services like DHCP, L3, FW, and others. - // Used to make network resources highly available. - AvailabilityZoneHints []string `json:"availability_zone_hints"` - - // Tags optionally set via extensions/attributestags - Tags []string `json:"tags"` - - // RevisionNumber optionally set via extensions/standard-attr-revisions - RevisionNumber int `json:"revision_number"` -} - -func (r *Network) UnmarshalJSON(b []byte) error { - type tmp Network - - // Support for older neutron time format - var s1 struct { - tmp - CreatedAt gophercloud.JSONRFC3339NoZ `json:"created_at"` - UpdatedAt gophercloud.JSONRFC3339NoZ `json:"updated_at"` - } - - err := json.Unmarshal(b, &s1) - if err == nil { - *r = Network(s1.tmp) - r.CreatedAt = time.Time(s1.CreatedAt) - r.UpdatedAt = time.Time(s1.UpdatedAt) - - return nil - } - - // Support for newer neutron time format - var s2 struct { - tmp - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - } - - err = json.Unmarshal(b, &s2) - if err != nil { - return err - } - - *r = Network(s2.tmp) - r.CreatedAt = time.Time(s2.CreatedAt) - r.UpdatedAt = time.Time(s2.UpdatedAt) - - return nil -} - -// NetworkPage is the page returned by a pager when traversing over a -// collection of networks. -type NetworkPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of networks has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r NetworkPage) NextPageURL() (string, error) { - var s struct { - Links []gophercloud.Link `json:"networks_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return gophercloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a NetworkPage struct is empty. -func (r NetworkPage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - is, err := ExtractNetworks(r) - return len(is) == 0, err -} - -// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct, -// and extracts the elements into a slice of Network structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractNetworks(r pagination.Page) ([]Network, error) { - var s []Network - err := ExtractNetworksInto(r, &s) - return s, err -} - -func ExtractNetworksInto(r pagination.Page, v interface{}) error { - return r.(NetworkPage).Result.ExtractIntoSlicePtr(v, "networks") -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go deleted file mode 100644 index 4a8fb1dc..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/networks/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package networks - -import "github.com/gophercloud/gophercloud" - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("networks", id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("networks") -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func listURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func createURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/doc.go deleted file mode 100644 index 8bb4468c..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/doc.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Package subnets contains functionality for working with Neutron subnet -resources. A subnet represents an IP address block that can be used to -assign IP addresses to virtual instances. Each subnet must have a CIDR and -must be associated with a network. IPs can either be selected from the whole -subnet CIDR or from allocation pools specified by the user. - -A subnet can also have a gateway, a list of DNS name servers, and host routes. -This information is pushed to instances whose interfaces are associated with -the subnet. - -Example to List Subnets - - listOpts := subnets.ListOpts{ - IPVersion: 4, - } - - allPages, err := subnets.List(networkClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allSubnets, err := subnets.ExtractSubnets(allPages) - if err != nil { - panic(err) - } - - for _, subnet := range allSubnets { - fmt.Printf("%+v\n", subnet) - } - -Example to Create a Subnet With Specified Gateway - - var gatewayIP = "192.168.199.1" - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22", - IPVersion: 4, - CIDR: "192.168.199.0/24", - GatewayIP: &gatewayIP, - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.199.2", - End: "192.168.199.254", - }, - }, - DNSNameservers: []string{"foo"}, - ServiceTypes: []string{"network:floatingip"}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Create a Subnet With No Gateway - - var noGateway = "" - - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - IPVersion: 4, - CIDR: "192.168.1.0/24", - GatewayIP: &noGateway, - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.1.2", - End: "192.168.1.254", - }, - }, - DNSNameservers: []string{}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Create a Subnet With a Default Gateway - - createOpts := subnets.CreateOpts{ - NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23", - IPVersion: 4, - CIDR: "192.168.1.0/24", - AllocationPools: []subnets.AllocationPool{ - { - Start: "192.168.1.2", - End: "192.168.1.254", - }, - }, - DNSNameservers: []string{}, - } - - subnet, err := subnets.Create(networkClient, createOpts).Extract() - if err != nil { - panic(err) - } - -Example to Update a Subnet - - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - dnsNameservers := []string{"8.8.8.8"} - serviceTypes := []string{"network:floatingip", "network:routed"} - name := "new_name" - - updateOpts := subnets.UpdateOpts{ - Name: &name, - DNSNameservers: &dnsNameservers, - ServiceTypes: &serviceTypes, - } - - subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Remove a Gateway From a Subnet - - var noGateway = "" - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - - updateOpts := subnets.UpdateOpts{ - GatewayIP: &noGateway, - } - - subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete a Subnet - - subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23" - err := subnets.Delete(networkClient, subnetID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package subnets diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go deleted file mode 100644 index 2e879075..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go +++ /dev/null @@ -1,261 +0,0 @@ -package subnets - -import ( - "fmt" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToSubnetListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the subnet attributes you want to see returned. SortKey allows you to sort -// by a particular subnet attribute. SortDir sets the direction, and is either -// `asc' or `desc'. Marker and Limit are used for pagination. -type ListOpts struct { - Name string `q:"name"` - Description string `q:"description"` - EnableDHCP *bool `q:"enable_dhcp"` - NetworkID string `q:"network_id"` - TenantID string `q:"tenant_id"` - ProjectID string `q:"project_id"` - IPVersion int `q:"ip_version"` - GatewayIP string `q:"gateway_ip"` - CIDR string `q:"cidr"` - IPv6AddressMode string `q:"ipv6_address_mode"` - IPv6RAMode string `q:"ipv6_ra_mode"` - ID string `q:"id"` - SubnetPoolID string `q:"subnetpool_id"` - Limit int `q:"limit"` - Marker string `q:"marker"` - SortKey string `q:"sort_key"` - SortDir string `q:"sort_dir"` - Tags string `q:"tags"` - TagsAny string `q:"tags-any"` - NotTags string `q:"not-tags"` - NotTagsAny string `q:"not-tags-any"` -} - -// ToSubnetListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToSubnetListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - return q.String(), err -} - -// List returns a Pager which allows you to iterate over a collection of -// subnets. It accepts a ListOpts struct, which allows you to filter and sort -// the returned collection for greater efficiency. -// -// Default policy settings return only those subnets that are owned by the tenant -// who submits the request, unless the request is submitted by a user with -// administrative rights. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToSubnetListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - return SubnetPage{pagination.LinkedPageBase{PageResult: r}} - }) -} - -// Get retrieves a specific subnet based on its unique ID. -func Get(c *gophercloud.ServiceClient, id string) (r GetResult) { - resp, err := c.Get(getURL(c, id), &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// CreateOptsBuilder allows extensions to add additional parameters to the -// List request. -type CreateOptsBuilder interface { - ToSubnetCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents the attributes used when creating a new subnet. -type CreateOpts struct { - // NetworkID is the UUID of the network the subnet will be associated with. - NetworkID string `json:"network_id" required:"true"` - - // CIDR is the address CIDR of the subnet. - CIDR string `json:"cidr,omitempty"` - - // Name is a human-readable name of the subnet. - Name string `json:"name,omitempty"` - - // Description of the subnet. - Description string `json:"description,omitempty"` - - // The UUID of the project who owns the Subnet. Only administrative users - // can specify a project UUID other than their own. - TenantID string `json:"tenant_id,omitempty"` - - // The UUID of the project who owns the Subnet. Only administrative users - // can specify a project UUID other than their own. - ProjectID string `json:"project_id,omitempty"` - - // AllocationPools are IP Address pools that will be available for DHCP. - AllocationPools []AllocationPool `json:"allocation_pools,omitempty"` - - // GatewayIP sets gateway information for the subnet. Setting to nil will - // cause a default gateway to automatically be created. Setting to an empty - // string will cause the subnet to be created with no gateway. Setting to - // an explicit address will set that address as the gateway. - GatewayIP *string `json:"gateway_ip,omitempty"` - - // IPVersion is the IP version for the subnet. - IPVersion gophercloud.IPVersion `json:"ip_version,omitempty"` - - // EnableDHCP will either enable to disable the DHCP service. - EnableDHCP *bool `json:"enable_dhcp,omitempty"` - - // DNSNameservers are the nameservers to be set via DHCP. - DNSNameservers []string `json:"dns_nameservers,omitempty"` - - // ServiceTypes are the service types associated with the subnet. - ServiceTypes []string `json:"service_types,omitempty"` - - // HostRoutes are any static host routes to be set via DHCP. - HostRoutes []HostRoute `json:"host_routes,omitempty"` - - // The IPv6 address modes specifies mechanisms for assigning IPv6 IP addresses. - IPv6AddressMode string `json:"ipv6_address_mode,omitempty"` - - // The IPv6 router advertisement specifies whether the networking service - // should transmit ICMPv6 packets. - IPv6RAMode string `json:"ipv6_ra_mode,omitempty"` - - // SubnetPoolID is the id of the subnet pool that subnet should be associated to. - SubnetPoolID string `json:"subnetpool_id,omitempty"` - - // Prefixlen is used when user creates a subnet from the subnetpool. It will - // overwrite the "default_prefixlen" value of the referenced subnetpool. - Prefixlen int `json:"prefixlen,omitempty"` -} - -// ToSubnetCreateMap builds a request body from CreateOpts. -func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { - b, err := gophercloud.BuildRequestBody(opts, "subnet") - if err != nil { - return nil, err - } - - if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" { - m["gateway_ip"] = nil - } - - return b, nil -} - -// Create accepts a CreateOpts struct and creates a new subnet using the values -// provided. You must remember to provide a valid NetworkID, CIDR and IP -// version. -func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToSubnetCreateMap() - if err != nil { - r.Err = err - return - } - resp, err := c.Post(createURL(c), b, &r.Body, nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - ToSubnetUpdateMap() (map[string]interface{}, error) -} - -// UpdateOpts represents the attributes used when updating an existing subnet. -type UpdateOpts struct { - // Name is a human-readable name of the subnet. - Name *string `json:"name,omitempty"` - - // Description of the subnet. - Description *string `json:"description,omitempty"` - - // AllocationPools are IP Address pools that will be available for DHCP. - AllocationPools []AllocationPool `json:"allocation_pools,omitempty"` - - // GatewayIP sets gateway information for the subnet. Setting to nil will - // cause a default gateway to automatically be created. Setting to an empty - // string will cause the subnet to be created with no gateway. Setting to - // an explicit address will set that address as the gateway. - GatewayIP *string `json:"gateway_ip,omitempty"` - - // DNSNameservers are the nameservers to be set via DHCP. - DNSNameservers *[]string `json:"dns_nameservers,omitempty"` - - // ServiceTypes are the service types associated with the subnet. - ServiceTypes *[]string `json:"service_types,omitempty"` - - // HostRoutes are any static host routes to be set via DHCP. - HostRoutes *[]HostRoute `json:"host_routes,omitempty"` - - // EnableDHCP will either enable to disable the DHCP service. - EnableDHCP *bool `json:"enable_dhcp,omitempty"` - - // RevisionNumber implements extension:standard-attr-revisions. If != "" it - // will set revision_number=%s. If the revision number does not match, the - // update will fail. - RevisionNumber *int `json:"-" h:"If-Match"` -} - -// ToSubnetUpdateMap builds a request body from UpdateOpts. -func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { - b, err := gophercloud.BuildRequestBody(opts, "subnet") - if err != nil { - return nil, err - } - - if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" { - m["gateway_ip"] = nil - } - - return b, nil -} - -// Update accepts a UpdateOpts struct and updates an existing subnet using the -// values provided. -func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToSubnetUpdateMap() - if err != nil { - r.Err = err - return - } - h, err := gophercloud.BuildHeaders(opts) - if err != nil { - r.Err = err - return - } - for k := range h { - if k == "If-Match" { - h[k] = fmt.Sprintf("revision_number=%s", h[k]) - } - } - - resp, err := c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ - MoreHeaders: h, - OkCodes: []int{200, 201}, - }) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} - -// Delete accepts a unique ID and deletes the subnet associated with it. -func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) { - resp, err := c.Delete(deleteURL(c, id), nil) - _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) - return -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/results.go deleted file mode 100644 index cd09b6f6..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/results.go +++ /dev/null @@ -1,162 +0,0 @@ -package subnets - -import ( - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -type commonResult struct { - gophercloud.Result -} - -// Extract is a function that accepts a result and extracts a subnet resource. -func (r commonResult) Extract() (*Subnet, error) { - var s struct { - Subnet *Subnet `json:"subnet"` - } - err := r.ExtractInto(&s) - return s.Subnet, err -} - -// CreateResult represents the result of a create operation. Call its Extract -// method to interpret it as a Subnet. -type CreateResult struct { - commonResult -} - -// GetResult represents the result of a get operation. Call its Extract -// method to interpret it as a Subnet. -type GetResult struct { - commonResult -} - -// UpdateResult represents the result of an update operation. Call its Extract -// method to interpret it as a Subnet. -type UpdateResult struct { - commonResult -} - -// DeleteResult represents the result of a delete operation. Call its -// ExtractErr method to determine if the request succeeded or failed. -type DeleteResult struct { - gophercloud.ErrResult -} - -// AllocationPool represents a sub-range of cidr available for dynamic -// allocation to ports, e.g. {Start: "10.0.0.2", End: "10.0.0.254"} -type AllocationPool struct { - Start string `json:"start"` - End string `json:"end"` -} - -// HostRoute represents a route that should be used by devices with IPs from -// a subnet (not including local subnet route). -type HostRoute struct { - DestinationCIDR string `json:"destination"` - NextHop string `json:"nexthop"` -} - -// Subnet represents a subnet. See package documentation for a top-level -// description of what this is. -type Subnet struct { - // UUID representing the subnet. - ID string `json:"id"` - - // UUID of the parent network. - NetworkID string `json:"network_id"` - - // Human-readable name for the subnet. Might not be unique. - Name string `json:"name"` - - // Description for the subnet. - Description string `json:"description"` - - // IP version, either `4' or `6'. - IPVersion int `json:"ip_version"` - - // CIDR representing IP range for this subnet, based on IP version. - CIDR string `json:"cidr"` - - // Default gateway used by devices in this subnet. - GatewayIP string `json:"gateway_ip"` - - // DNS name servers used by hosts in this subnet. - DNSNameservers []string `json:"dns_nameservers"` - - // Service types associated with the subnet. - ServiceTypes []string `json:"service_types"` - - // Sub-ranges of CIDR available for dynamic allocation to ports. - // See AllocationPool. - AllocationPools []AllocationPool `json:"allocation_pools"` - - // Routes that should be used by devices with IPs from this subnet - // (not including local subnet route). - HostRoutes []HostRoute `json:"host_routes"` - - // Specifies whether DHCP is enabled for this subnet or not. - EnableDHCP bool `json:"enable_dhcp"` - - // TenantID is the project owner of the subnet. - TenantID string `json:"tenant_id"` - - // ProjectID is the project owner of the subnet. - ProjectID string `json:"project_id"` - - // The IPv6 address modes specifies mechanisms for assigning IPv6 IP addresses. - IPv6AddressMode string `json:"ipv6_address_mode"` - - // The IPv6 router advertisement specifies whether the networking service - // should transmit ICMPv6 packets. - IPv6RAMode string `json:"ipv6_ra_mode"` - - // SubnetPoolID is the id of the subnet pool associated with the subnet. - SubnetPoolID string `json:"subnetpool_id"` - - // Tags optionally set via extensions/attributestags - Tags []string `json:"tags"` - - // RevisionNumber optionally set via extensions/standard-attr-revisions - RevisionNumber int `json:"revision_number"` -} - -// SubnetPage is the page returned by a pager when traversing over a collection -// of subnets. -type SubnetPage struct { - pagination.LinkedPageBase -} - -// NextPageURL is invoked when a paginated collection of subnets has reached -// the end of a page and the pager seeks to traverse over a new one. In order -// to do this, it needs to construct the next page's URL. -func (r SubnetPage) NextPageURL() (string, error) { - var s struct { - Links []gophercloud.Link `json:"subnets_links"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - return gophercloud.ExtractNextURL(s.Links) -} - -// IsEmpty checks whether a SubnetPage struct is empty. -func (r SubnetPage) IsEmpty() (bool, error) { - if r.StatusCode == 204 { - return true, nil - } - - is, err := ExtractSubnets(r) - return len(is) == 0, err -} - -// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct, -// and extracts the elements into a slice of Subnet structs. In other words, -// a generic collection is mapped into a relevant slice. -func ExtractSubnets(r pagination.Page) ([]Subnet, error) { - var s struct { - Subnets []Subnet `json:"subnets"` - } - err := (r.(SubnetPage)).ExtractInto(&s) - return s.Subnets, err -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/urls.go deleted file mode 100644 index 7a4f2f7d..00000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/urls.go +++ /dev/null @@ -1,31 +0,0 @@ -package subnets - -import "github.com/gophercloud/gophercloud" - -func resourceURL(c *gophercloud.ServiceClient, id string) string { - return c.ServiceURL("subnets", id) -} - -func rootURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("subnets") -} - -func listURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func getURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func createURL(c *gophercloud.ServiceClient) string { - return rootURL(c) -} - -func updateURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} - -func deleteURL(c *gophercloud.ServiceClient, id string) string { - return resourceURL(c, id) -} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/http.go b/vendor/github.com/gophercloud/gophercloud/pagination/http.go deleted file mode 100644 index 7845cda1..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/http.go +++ /dev/null @@ -1,62 +0,0 @@ -package pagination - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "net/url" - "strings" - - "github.com/gophercloud/gophercloud" -) - -// PageResult stores the HTTP response that returned the current page of results. -type PageResult struct { - gophercloud.Result - url.URL -} - -// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the -// results, interpreting it as JSON if the content type indicates. -func PageResultFrom(resp *http.Response) (PageResult, error) { - var parsedBody interface{} - - defer resp.Body.Close() - rawBody, err := ioutil.ReadAll(resp.Body) - if err != nil { - return PageResult{}, err - } - - if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { - err = json.Unmarshal(rawBody, &parsedBody) - if err != nil { - return PageResult{}, err - } - } else { - parsedBody = rawBody - } - - return PageResultFromParsed(resp, parsedBody), err -} - -// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its -// body parsed as JSON (and closed). -func PageResultFromParsed(resp *http.Response, body interface{}) PageResult { - return PageResult{ - Result: gophercloud.Result{ - Body: body, - StatusCode: resp.StatusCode, - Header: resp.Header, - }, - URL: *resp.Request.URL, - } -} - -// Request performs an HTTP request and extracts the http.Response from the result. -func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) { - return client.Get(url, nil, &gophercloud.RequestOpts{ - MoreHeaders: headers, - OkCodes: []int{200, 204, 300}, - KeepResponseBody: true, - }) -} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/linked.go b/vendor/github.com/gophercloud/gophercloud/pagination/linked.go deleted file mode 100644 index a664e056..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/linked.go +++ /dev/null @@ -1,92 +0,0 @@ -package pagination - -import ( - "fmt" - "reflect" - - "github.com/gophercloud/gophercloud" -) - -// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result. -type LinkedPageBase struct { - PageResult - - // LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer. - // If any link along the path is missing, an empty URL will be returned. - // If any link results in an unexpected value type, an error will be returned. - // When left as "nil", []string{"links", "next"} will be used as a default. - LinkPath []string -} - -// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present. -// It assumes that the links are available in a "links" element of the top-level response object. -// If this is not the case, override NextPageURL on your result type. -func (current LinkedPageBase) NextPageURL() (string, error) { - var path []string - var key string - - if current.LinkPath == nil { - path = []string{"links", "next"} - } else { - path = current.LinkPath - } - - submap, ok := current.Body.(map[string]interface{}) - if !ok { - err := gophercloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return "", err - } - - for { - key, path = path[0], path[1:] - - value, ok := submap[key] - if !ok { - return "", nil - } - - if len(path) > 0 { - submap, ok = value.(map[string]interface{}) - if !ok { - err := gophercloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - return "", err - } - } else { - if value == nil { - // Actual null element. - return "", nil - } - - url, ok := value.(string) - if !ok { - err := gophercloud.ErrUnexpectedType{} - err.Expected = "string" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) - return "", err - } - - return url, nil - } - } -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current LinkedPageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := gophercloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the linked page's body. This method is needed to satisfy the -// Page interface. -func (current LinkedPageBase) GetBody() interface{} { - return current.Body -} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/marker.go b/vendor/github.com/gophercloud/gophercloud/pagination/marker.go deleted file mode 100644 index 52e53bae..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/marker.go +++ /dev/null @@ -1,58 +0,0 @@ -package pagination - -import ( - "fmt" - "reflect" - - "github.com/gophercloud/gophercloud" -) - -// MarkerPage is a stricter Page interface that describes additional functionality required for use with NewMarkerPager. -// For convenience, embed the MarkedPageBase struct. -type MarkerPage interface { - Page - - // LastMarker returns the last "marker" value on this page. - LastMarker() (string, error) -} - -// MarkerPageBase is a page in a collection that's paginated by "limit" and "marker" query parameters. -type MarkerPageBase struct { - PageResult - - // Owner is a reference to the embedding struct. - Owner MarkerPage -} - -// NextPageURL generates the URL for the page of results after this one. -func (current MarkerPageBase) NextPageURL() (string, error) { - currentURL := current.URL - - mark, err := current.Owner.LastMarker() - if err != nil { - return "", err - } - - q := currentURL.Query() - q.Set("marker", mark) - currentURL.RawQuery = q.Encode() - - return currentURL.String(), nil -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current MarkerPageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := gophercloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the linked page's body. This method is needed to satisfy the -// Page interface. -func (current MarkerPageBase) GetBody() interface{} { - return current.Body -} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/pager.go b/vendor/github.com/gophercloud/gophercloud/pagination/pager.go deleted file mode 100644 index 1dec2703..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/pager.go +++ /dev/null @@ -1,254 +0,0 @@ -package pagination - -import ( - "errors" - "fmt" - "net/http" - "reflect" - "strings" - - "github.com/gophercloud/gophercloud" -) - -var ( - // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. - ErrPageNotAvailable = errors.New("The requested page does not exist.") -) - -// Page must be satisfied by the result type of any resource collection. -// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. -// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, -// instead. -// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type -// will need to implement. -type Page interface { - // NextPageURL generates the URL for the page of data that follows this collection. - // Return "" if no such page exists. - NextPageURL() (string, error) - - // IsEmpty returns true if this Page has no items in it. - IsEmpty() (bool, error) - - // GetBody returns the Page Body. This is used in the `AllPages` method. - GetBody() interface{} -} - -// Pager knows how to advance through a specific resource collection, one page at a time. -type Pager struct { - client *gophercloud.ServiceClient - - initialURL string - - createPage func(r PageResult) Page - - firstPage Page - - Err error - - // Headers supplies additional HTTP headers to populate on each paged request. - Headers map[string]string -} - -// NewPager constructs a manually-configured pager. -// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. -func NewPager(client *gophercloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { - return Pager{ - client: client, - initialURL: initialURL, - createPage: createPage, - } -} - -// WithPageCreator returns a new Pager that substitutes a different page creation function. This is -// useful for overriding List functions in delegation. -func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { - return Pager{ - client: p.client, - initialURL: p.initialURL, - createPage: createPage, - } -} - -func (p Pager) fetchNextPage(url string) (Page, error) { - resp, err := Request(p.client, p.Headers, url) - if err != nil { - return nil, err - } - - remembered, err := PageResultFrom(resp) - if err != nil { - return nil, err - } - - return p.createPage(remembered), nil -} - -// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. -// Return "false" from the handler to prematurely stop iterating. -func (p Pager) EachPage(handler func(Page) (bool, error)) error { - if p.Err != nil { - return p.Err - } - currentURL := p.initialURL - for { - var currentPage Page - - // if first page has already been fetched, no need to fetch it again - if p.firstPage != nil { - currentPage = p.firstPage - p.firstPage = nil - } else { - var err error - currentPage, err = p.fetchNextPage(currentURL) - if err != nil { - return err - } - } - - empty, err := currentPage.IsEmpty() - if err != nil { - return err - } - if empty { - return nil - } - - ok, err := handler(currentPage) - if err != nil { - return err - } - if !ok { - return nil - } - - currentURL, err = currentPage.NextPageURL() - if err != nil { - return err - } - if currentURL == "" { - return nil - } - } -} - -// AllPages returns all the pages from a `List` operation in a single page, -// allowing the user to retrieve all the pages at once. -func (p Pager) AllPages() (Page, error) { - if p.Err != nil { - return nil, p.Err - } - // pagesSlice holds all the pages until they get converted into as Page Body. - var pagesSlice []interface{} - // body will contain the final concatenated Page body. - var body reflect.Value - - // Grab a first page to ascertain the page body type. - firstPage, err := p.fetchNextPage(p.initialURL) - if err != nil { - return nil, err - } - // Store the page type so we can use reflection to create a new mega-page of - // that type. - pageType := reflect.TypeOf(firstPage) - - // if it's a single page, just return the firstPage (first page) - if _, found := pageType.FieldByName("SinglePageBase"); found { - return firstPage, nil - } - - // store the first page to avoid getting it twice - p.firstPage = firstPage - - // Switch on the page body type. Recognized types are `map[string]interface{}`, - // `[]byte`, and `[]interface{}`. - switch pb := firstPage.GetBody().(type) { - case map[string]interface{}: - // key is the map key for the page body if the body type is `map[string]interface{}`. - var key string - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().(map[string]interface{}) - for k, v := range b { - // If it's a linked page, we don't want the `links`, we want the other one. - if !strings.HasSuffix(k, "links") { - // check the field's type. we only want []interface{} (which is really []map[string]interface{}) - switch vt := v.(type) { - case []interface{}: - key = k - pagesSlice = append(pagesSlice, vt...) - } - } - } - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `map[string]interface{}` - body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice))) - body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice)) - case []byte: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]byte) - pagesSlice = append(pagesSlice, b) - // seperate pages with a comma - pagesSlice = append(pagesSlice, []byte{10}) - return true, nil - }) - if err != nil { - return nil, err - } - if len(pagesSlice) > 0 { - // Remove the trailing comma. - pagesSlice = pagesSlice[:len(pagesSlice)-1] - } - var b []byte - // Combine the slice of slices in to a single slice. - for _, slice := range pagesSlice { - b = append(b, slice.([]byte)...) - } - // Set body to value of type `bytes`. - body = reflect.New(reflect.TypeOf(b)).Elem() - body.SetBytes(b) - case []interface{}: - // Iterate over the pages to concatenate the bodies. - err = p.EachPage(func(page Page) (bool, error) { - b := page.GetBody().([]interface{}) - pagesSlice = append(pagesSlice, b...) - return true, nil - }) - if err != nil { - return nil, err - } - // Set body to value of type `[]interface{}` - body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice)) - for i, s := range pagesSlice { - body.Index(i).Set(reflect.ValueOf(s)) - } - default: - err := gophercloud.ErrUnexpectedType{} - err.Expected = "map[string]interface{}/[]byte/[]interface{}" - err.Actual = fmt.Sprintf("%T", pb) - return nil, err - } - - // Each `Extract*` function is expecting a specific type of page coming back, - // otherwise the type assertion in those functions will fail. pageType is needed - // to create a type in this method that has the same type that the `Extract*` - // function is expecting and set the Body of that object to the concatenated - // pages. - page := reflect.New(pageType) - // Set the page body to be the concatenated pages. - page.Elem().FieldByName("Body").Set(body) - // Set any additional headers that were pass along. The `objectstorage` pacakge, - // for example, passes a Content-Type header. - h := make(http.Header) - for k, v := range p.Headers { - h.Add(k, v) - } - page.Elem().FieldByName("Header").Set(reflect.ValueOf(h)) - // Type assert the page to a Page interface so that the type assertion in the - // `Extract*` methods will work. - return page.Elem().Interface().(Page), err -} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go b/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go deleted file mode 100644 index 912daea3..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go +++ /dev/null @@ -1,4 +0,0 @@ -/* -Package pagination contains utilities and convenience structs that implement common pagination idioms within OpenStack APIs. -*/ -package pagination diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/single.go b/vendor/github.com/gophercloud/gophercloud/pagination/single.go deleted file mode 100644 index 4251d649..00000000 --- a/vendor/github.com/gophercloud/gophercloud/pagination/single.go +++ /dev/null @@ -1,33 +0,0 @@ -package pagination - -import ( - "fmt" - "reflect" - - "github.com/gophercloud/gophercloud" -) - -// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once. -type SinglePageBase PageResult - -// NextPageURL always returns "" to indicate that there are no more pages to return. -func (current SinglePageBase) NextPageURL() (string, error) { - return "", nil -} - -// IsEmpty satisifies the IsEmpty method of the Page interface -func (current SinglePageBase) IsEmpty() (bool, error) { - if b, ok := current.Body.([]interface{}); ok { - return len(b) == 0, nil - } - err := gophercloud.ErrUnexpectedType{} - err.Expected = "[]interface{}" - err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) - return true, err -} - -// GetBody returns the single page's body. This method is needed to satisfy the -// Page interface. -func (current SinglePageBase) GetBody() interface{} { - return current.Body -} diff --git a/vendor/github.com/gophercloud/gophercloud/params.go b/vendor/github.com/gophercloud/gophercloud/params.go deleted file mode 100644 index 17b200cd..00000000 --- a/vendor/github.com/gophercloud/gophercloud/params.go +++ /dev/null @@ -1,496 +0,0 @@ -package gophercloud - -import ( - "encoding/json" - "fmt" - "net/url" - "reflect" - "strconv" - "strings" - "time" -) - -/* -BuildRequestBody builds a map[string]interface from the given `struct`. If -parent is not an empty string, the final map[string]interface returned will -encapsulate the built one. For example: - - disk := 1 - createOpts := flavors.CreateOpts{ - ID: "1", - Name: "m1.tiny", - Disk: &disk, - RAM: 512, - VCPUs: 1, - RxTxFactor: 1.0, - } - - body, err := gophercloud.BuildRequestBody(createOpts, "flavor") - -The above example can be run as-is, however it is recommended to look at how -BuildRequestBody is used within Gophercloud to more fully understand how it -fits within the request process as a whole rather than use it directly as shown -above. -*/ -func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]interface{}) - if optsValue.Kind() == reflect.Struct { - //fmt.Printf("optsValue.Kind() is a reflect.Struct: %+v\n", optsValue.Kind()) - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - - if f.Name != strings.Title(f.Name) { - //fmt.Printf("Skipping field: %s...\n", f.Name) - continue - } - - //fmt.Printf("Starting on field: %s...\n", f.Name) - - zero := isZero(v) - //fmt.Printf("v is zero?: %v\n", zero) - - // if the field has a required tag that's set to "true" - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - //fmt.Printf("Checking required field [%s]:\n\tv: %+v\n\tisZero:%v\n", f.Name, v.Interface(), zero) - // if the field's value is zero, return a missing-argument error - if zero { - // if the field has a 'required' tag, it can't have a zero-value - err := ErrMissingInput{} - err.Argument = f.Name - return nil, err - } - } - - if xorTag := f.Tag.Get("xor"); xorTag != "" { - //fmt.Printf("Checking `xor` tag for field [%s] with value %+v:\n\txorTag: %s\n", f.Name, v, xorTag) - xorField := optsValue.FieldByName(xorTag) - var xorFieldIsZero bool - if reflect.ValueOf(xorField.Interface()) == reflect.Zero(xorField.Type()) { - xorFieldIsZero = true - } else { - if xorField.Kind() == reflect.Ptr { - xorField = xorField.Elem() - } - xorFieldIsZero = isZero(xorField) - } - if !(zero != xorFieldIsZero) { - err := ErrMissingInput{} - err.Argument = fmt.Sprintf("%s/%s", f.Name, xorTag) - err.Info = fmt.Sprintf("Exactly one of %s and %s must be provided", f.Name, xorTag) - return nil, err - } - } - - if orTag := f.Tag.Get("or"); orTag != "" { - //fmt.Printf("Checking `or` tag for field with:\n\tname: %+v\n\torTag:%s\n", f.Name, orTag) - //fmt.Printf("field is zero?: %v\n", zero) - if zero { - orField := optsValue.FieldByName(orTag) - var orFieldIsZero bool - if reflect.ValueOf(orField.Interface()) == reflect.Zero(orField.Type()) { - orFieldIsZero = true - } else { - if orField.Kind() == reflect.Ptr { - orField = orField.Elem() - } - orFieldIsZero = isZero(orField) - } - if orFieldIsZero { - err := ErrMissingInput{} - err.Argument = fmt.Sprintf("%s/%s", f.Name, orTag) - err.Info = fmt.Sprintf("At least one of %s and %s must be provided", f.Name, orTag) - return nil, err - } - } - } - - jsonTag := f.Tag.Get("json") - if jsonTag == "-" { - continue - } - - if v.Kind() == reflect.Slice || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Slice) { - sliceValue := v - if sliceValue.Kind() == reflect.Ptr { - sliceValue = sliceValue.Elem() - } - - for i := 0; i < sliceValue.Len(); i++ { - element := sliceValue.Index(i) - if element.Kind() == reflect.Struct || (element.Kind() == reflect.Ptr && element.Elem().Kind() == reflect.Struct) { - _, err := BuildRequestBody(element.Interface(), "") - if err != nil { - return nil, err - } - } - } - } - if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { - if zero { - //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) - if jsonTag != "" { - jsonTagPieces := strings.Split(jsonTag, ",") - if len(jsonTagPieces) > 1 && jsonTagPieces[1] == "omitempty" { - if v.CanSet() { - if !v.IsNil() { - if v.Kind() == reflect.Ptr { - v.Set(reflect.Zero(v.Type())) - } - } - //fmt.Printf("value after change: %+v\n", optsValue.Field(i)) - } - } - } - continue - } - - //fmt.Printf("Calling BuildRequestBody with:\n\tv: %+v\n\tf.Name:%s\n", v.Interface(), f.Name) - _, err := BuildRequestBody(v.Interface(), f.Name) - if err != nil { - return nil, err - } - } - } - - //fmt.Printf("opts: %+v \n", opts) - - b, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - //fmt.Printf("string(b): %s\n", string(b)) - - err = json.Unmarshal(b, &optsMap) - if err != nil { - return nil, err - } - - //fmt.Printf("optsMap: %+v\n", optsMap) - - if parent != "" { - optsMap = map[string]interface{}{parent: optsMap} - } - //fmt.Printf("optsMap after parent added: %+v\n", optsMap) - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("Options type is not a struct.") -} - -// EnabledState is a convenience type, mostly used in Create and Update -// operations. Because the zero value of a bool is FALSE, we need to use a -// pointer instead to indicate zero-ness. -type EnabledState *bool - -// Convenience vars for EnabledState values. -var ( - iTrue = true - iFalse = false - - Enabled EnabledState = &iTrue - Disabled EnabledState = &iFalse -) - -// IPVersion is a type for the possible IP address versions. Valid instances -// are IPv4 and IPv6 -type IPVersion int - -const ( - // IPv4 is used for IP version 4 addresses - IPv4 IPVersion = 4 - // IPv6 is used for IP version 6 addresses - IPv6 IPVersion = 6 -) - -// IntToPointer is a function for converting integers into integer pointers. -// This is useful when passing in options to operations. -func IntToPointer(i int) *int { - return &i -} - -/* -MaybeString is an internal function to be used by request methods in individual -resource packages. - -It takes a string that might be a zero value and returns either a pointer to its -address or nil. This is useful for allowing users to conveniently omit values -from an options struct by leaving them zeroed, but still pass nil to the JSON -serializer so they'll be omitted from the request body. -*/ -func MaybeString(original string) *string { - if original != "" { - return &original - } - return nil -} - -/* -MaybeInt is an internal function to be used by request methods in individual -resource packages. - -Like MaybeString, it accepts an int that may or may not be a zero value, and -returns either a pointer to its address or nil. It's intended to hint that the -JSON serializer should omit its field. -*/ -func MaybeInt(original int) *int { - if original != 0 { - return &original - } - return nil -} - -/* -func isUnderlyingStructZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Ptr: - return isUnderlyingStructZero(v.Elem()) - default: - return isZero(v) - } -} -*/ - -var t time.Time - -func isZero(v reflect.Value) bool { - //fmt.Printf("\n\nchecking isZero for value: %+v\n", v) - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - return true - } - return false - case reflect.Func, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - z := true - for i := 0; i < v.Len(); i++ { - z = z && isZero(v.Index(i)) - } - return z - case reflect.Struct: - if v.Type() == reflect.TypeOf(t) { - if v.Interface().(time.Time).IsZero() { - return true - } - return false - } - z := true - for i := 0; i < v.NumField(); i++ { - z = z && isZero(v.Field(i)) - } - return z - } - // Compare other types directly: - z := reflect.Zero(v.Type()) - //fmt.Printf("zero type for value: %+v\n\n\n", z) - return v.Interface() == z.Interface() -} - -/* -BuildQueryString is an internal function to be used by request methods in -individual resource packages. - -It accepts a tagged structure and expands it into a URL struct. Field names are -converted into query parameters based on a "q" tag. For example: - - type struct Something { - Bar string `q:"x_bar"` - Baz int `q:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into "?x_bar=AAA&lorem_ipsum=BBB". - -The struct's fields may be strings, integers, or boolean values. Fields left at -their type's zero value will be omitted from the query. -*/ -func BuildQueryString(opts interface{}) (*url.URL, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - params := url.Values{} - - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - qTag := f.Tag.Get("q") - - // if the field has a 'q' tag, it goes in the query string - if qTag != "" { - tags := strings.Split(qTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - loop: - switch v.Kind() { - case reflect.Ptr: - v = v.Elem() - goto loop - case reflect.String: - params.Add(tags[0], v.String()) - case reflect.Int: - params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) - case reflect.Bool: - params.Add(tags[0], strconv.FormatBool(v.Bool())) - case reflect.Slice: - switch v.Type().Elem() { - case reflect.TypeOf(0): - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10)) - } - default: - for i := 0; i < v.Len(); i++ { - params.Add(tags[0], v.Index(i).String()) - } - } - case reflect.Map: - if v.Type().Key().Kind() == reflect.String && v.Type().Elem().Kind() == reflect.String { - var s []string - for _, k := range v.MapKeys() { - value := v.MapIndex(k).String() - s = append(s, fmt.Sprintf("'%s':'%s'", k.String(), value)) - } - params.Add(tags[0], fmt.Sprintf("{%s}", strings.Join(s, ", "))) - } - } - } else { - // if the field has a 'required' tag, it can't have a zero-value - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name) - } - } - } - } - - return &url.URL{RawQuery: params.Encode()}, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return nil, fmt.Errorf("Options type is not a struct.") -} - -/* -BuildHeaders is an internal function to be used by request methods in -individual resource packages. - -It accepts an arbitrary tagged structure and produces a string map that's -suitable for use as the HTTP headers of an outgoing request. Field names are -mapped to header names based in "h" tags. - - type struct Something { - Bar string `h:"x_bar"` - Baz int `h:"lorem_ipsum"` - } - - instance := Something{ - Bar: "AAA", - Baz: "BBB", - } - -will be converted into: - - map[string]string{ - "x_bar": "AAA", - "lorem_ipsum": "BBB", - } - -Untagged fields and fields left at their zero values are skipped. Integers, -booleans and string values are supported. -*/ -func BuildHeaders(opts interface{}) (map[string]string, error) { - optsValue := reflect.ValueOf(opts) - if optsValue.Kind() == reflect.Ptr { - optsValue = optsValue.Elem() - } - - optsType := reflect.TypeOf(opts) - if optsType.Kind() == reflect.Ptr { - optsType = optsType.Elem() - } - - optsMap := make(map[string]string) - if optsValue.Kind() == reflect.Struct { - for i := 0; i < optsValue.NumField(); i++ { - v := optsValue.Field(i) - f := optsType.Field(i) - hTag := f.Tag.Get("h") - - // if the field has a 'h' tag, it goes in the header - if hTag != "" { - tags := strings.Split(hTag, ",") - - // if the field is set, add it to the slice of query pieces - if !isZero(v) { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - switch v.Kind() { - case reflect.String: - optsMap[tags[0]] = v.String() - case reflect.Int: - optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) - case reflect.Int64: - optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) - case reflect.Bool: - optsMap[tags[0]] = strconv.FormatBool(v.Bool()) - } - } else { - // if the field has a 'required' tag, it can't have a zero-value - if requiredTag := f.Tag.Get("required"); requiredTag == "true" { - return optsMap, fmt.Errorf("Required header [%s] not set.", f.Name) - } - } - } - - } - return optsMap, nil - } - // Return an error if the underlying type of 'opts' isn't a struct. - return optsMap, fmt.Errorf("Options type is not a struct.") -} - -// IDSliceToQueryString takes a slice of elements and converts them into a query -// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the -// result would be `?name=20&name=40&name=60' -func IDSliceToQueryString(name string, ids []int) string { - str := "" - for k, v := range ids { - if k == 0 { - str += "?" - } else { - str += "&" - } - str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) - } - return str -} - -// IntWithinRange returns TRUE if an integer falls within a defined range, and -// FALSE if not. -func IntWithinRange(val, min, max int) bool { - return val > min && val < max -} diff --git a/vendor/github.com/gophercloud/gophercloud/provider_client.go b/vendor/github.com/gophercloud/gophercloud/provider_client.go deleted file mode 100644 index 1ff54b81..00000000 --- a/vendor/github.com/gophercloud/gophercloud/provider_client.go +++ /dev/null @@ -1,652 +0,0 @@ -package gophercloud - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "io" - "io/ioutil" - "net/http" - "strings" - "sync" -) - -// DefaultUserAgent is the default User-Agent string set in the request header. -const ( - DefaultUserAgent = "gophercloud/v1.11.0" - DefaultMaxBackoffRetries = 60 -) - -// UserAgent represents a User-Agent header. -type UserAgent struct { - // prepend is the slice of User-Agent strings to prepend to DefaultUserAgent. - // All the strings to prepend are accumulated and prepended in the Join method. - prepend []string -} - -type RetryBackoffFunc func(context.Context, *ErrUnexpectedResponseCode, error, uint) error - -// RetryFunc is a catch-all function for retrying failed API requests. -// If it returns nil, the request will be retried. If it returns an error, -// the request method will exit with that error. failCount is the number of -// times the request has failed (starting at 1). -type RetryFunc func(context context.Context, method, url string, options *RequestOpts, err error, failCount uint) error - -// Prepend prepends a user-defined string to the default User-Agent string. Users -// may pass in one or more strings to prepend. -func (ua *UserAgent) Prepend(s ...string) { - ua.prepend = append(s, ua.prepend...) -} - -// Join concatenates all the user-defined User-Agend strings with the default -// Gophercloud User-Agent string. -func (ua *UserAgent) Join() string { - uaSlice := append(ua.prepend, DefaultUserAgent) - return strings.Join(uaSlice, " ") -} - -// ProviderClient stores details that are required to interact with any -// services within a specific provider's API. -// -// Generally, you acquire a ProviderClient by calling the NewClient method in -// the appropriate provider's child package, providing whatever authentication -// credentials are required. -type ProviderClient struct { - // IdentityBase is the base URL used for a particular provider's identity - // service - it will be used when issuing authenticatation requests. It - // should point to the root resource of the identity service, not a specific - // identity version. - IdentityBase string - - // IdentityEndpoint is the identity endpoint. This may be a specific version - // of the identity service. If this is the case, this endpoint is used rather - // than querying versions first. - IdentityEndpoint string - - // TokenID is the ID of the most recently issued valid token. - // NOTE: Aside from within a custom ReauthFunc, this field shouldn't be set by an application. - // To safely read or write this value, call `Token` or `SetToken`, respectively - TokenID string - - // EndpointLocator describes how this provider discovers the endpoints for - // its constituent services. - EndpointLocator EndpointLocator - - // HTTPClient allows users to interject arbitrary http, https, or other transit behaviors. - HTTPClient http.Client - - // UserAgent represents the User-Agent header in the HTTP request. - UserAgent UserAgent - - // ReauthFunc is the function used to re-authenticate the user if the request - // fails with a 401 HTTP response code. This a needed because there may be multiple - // authentication functions for different Identity service versions. - ReauthFunc func() error - - // Throwaway determines whether if this client is a throw-away client. It's a copy of user's provider client - // with the token and reauth func zeroed. Such client can be used to perform reauthorization. - Throwaway bool - - // Context is the context passed to the HTTP request. - Context context.Context - - // Retry backoff func is called when rate limited. - RetryBackoffFunc RetryBackoffFunc - - // MaxBackoffRetries set the maximum number of backoffs. When not set, defaults to DefaultMaxBackoffRetries - MaxBackoffRetries uint - - // A general failed request handler method - this is always called in the end if a request failed. Leave as nil - // to abort when an error is encountered. - RetryFunc RetryFunc - - // mut is a mutex for the client. It protects read and write access to client attributes such as getting - // and setting the TokenID. - mut *sync.RWMutex - - // reauthmut is a mutex for reauthentication it attempts to ensure that only one reauthentication - // attempt happens at one time. - reauthmut *reauthlock - - authResult AuthResult -} - -// reauthlock represents a set of attributes used to help in the reauthentication process. -type reauthlock struct { - sync.RWMutex - ongoing *reauthFuture -} - -// reauthFuture represents future result of the reauthentication process. -// while done channel is not closed, reauthentication is in progress. -// when done channel is closed, err contains the result of reauthentication. -type reauthFuture struct { - done chan struct{} - err error -} - -func newReauthFuture() *reauthFuture { - return &reauthFuture{ - make(chan struct{}), - nil, - } -} - -func (f *reauthFuture) Set(err error) { - f.err = err - close(f.done) -} - -func (f *reauthFuture) Get() error { - <-f.done - return f.err -} - -// AuthenticatedHeaders returns a map of HTTP headers that are common for all -// authenticated service requests. Blocks if Reauthenticate is in progress. -func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) { - if client.IsThrowaway() { - return - } - if client.reauthmut != nil { - // If a Reauthenticate is in progress, wait for it to complete. - client.reauthmut.Lock() - ongoing := client.reauthmut.ongoing - client.reauthmut.Unlock() - if ongoing != nil { - _ = ongoing.Get() - } - } - t := client.Token() - if t == "" { - return - } - return map[string]string{"X-Auth-Token": t} -} - -// UseTokenLock creates a mutex that is used to allow safe concurrent access to the auth token. -// If the application's ProviderClient is not used concurrently, this doesn't need to be called. -func (client *ProviderClient) UseTokenLock() { - client.mut = new(sync.RWMutex) - client.reauthmut = new(reauthlock) -} - -// GetAuthResult returns the result from the request that was used to obtain a -// provider client's Keystone token. -// -// The result is nil when authentication has not yet taken place, when the token -// was set manually with SetToken(), or when a ReauthFunc was used that does not -// record the AuthResult. -func (client *ProviderClient) GetAuthResult() AuthResult { - if client.mut != nil { - client.mut.RLock() - defer client.mut.RUnlock() - } - return client.authResult -} - -// Token safely reads the value of the auth token from the ProviderClient. Applications should -// call this method to access the token instead of the TokenID field -func (client *ProviderClient) Token() string { - if client.mut != nil { - client.mut.RLock() - defer client.mut.RUnlock() - } - return client.TokenID -} - -// SetToken safely sets the value of the auth token in the ProviderClient. Applications may -// use this method in a custom ReauthFunc. -// -// WARNING: This function is deprecated. Use SetTokenAndAuthResult() instead. -func (client *ProviderClient) SetToken(t string) { - if client.mut != nil { - client.mut.Lock() - defer client.mut.Unlock() - } - client.TokenID = t - client.authResult = nil -} - -// SetTokenAndAuthResult safely sets the value of the auth token in the -// ProviderClient and also records the AuthResult that was returned from the -// token creation request. Applications may call this in a custom ReauthFunc. -func (client *ProviderClient) SetTokenAndAuthResult(r AuthResult) error { - tokenID := "" - var err error - if r != nil { - tokenID, err = r.ExtractTokenID() - if err != nil { - return err - } - } - - if client.mut != nil { - client.mut.Lock() - defer client.mut.Unlock() - } - client.TokenID = tokenID - client.authResult = r - return nil -} - -// CopyTokenFrom safely copies the token from another ProviderClient into the -// this one. -func (client *ProviderClient) CopyTokenFrom(other *ProviderClient) { - if client.mut != nil { - client.mut.Lock() - defer client.mut.Unlock() - } - if other.mut != nil && other.mut != client.mut { - other.mut.RLock() - defer other.mut.RUnlock() - } - client.TokenID = other.TokenID - client.authResult = other.authResult -} - -// IsThrowaway safely reads the value of the client Throwaway field. -func (client *ProviderClient) IsThrowaway() bool { - if client.reauthmut != nil { - client.reauthmut.RLock() - defer client.reauthmut.RUnlock() - } - return client.Throwaway -} - -// SetThrowaway safely sets the value of the client Throwaway field. -func (client *ProviderClient) SetThrowaway(v bool) { - if client.reauthmut != nil { - client.reauthmut.Lock() - defer client.reauthmut.Unlock() - } - client.Throwaway = v -} - -// Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is -// called because of a 401 response, the caller may pass the previous token. In -// this case, the reauthentication can be skipped if another thread has already -// reauthenticated in the meantime. If no previous token is known, an empty -// string should be passed instead to force unconditional reauthentication. -func (client *ProviderClient) Reauthenticate(previousToken string) error { - if client.ReauthFunc == nil { - return nil - } - - if client.reauthmut == nil { - return client.ReauthFunc() - } - - future := newReauthFuture() - - // Check if a Reauthenticate is in progress, or start one if not. - client.reauthmut.Lock() - ongoing := client.reauthmut.ongoing - if ongoing == nil { - client.reauthmut.ongoing = future - } - client.reauthmut.Unlock() - - // If Reauthenticate is running elsewhere, wait for its result. - if ongoing != nil { - return ongoing.Get() - } - - // Perform the actual reauthentication. - var err error - if previousToken == "" || client.TokenID == previousToken { - err = client.ReauthFunc() - } else { - err = nil - } - - // Mark Reauthenticate as finished. - client.reauthmut.Lock() - client.reauthmut.ongoing.Set(err) - client.reauthmut.ongoing = nil - client.reauthmut.Unlock() - - return err -} - -// RequestOpts customizes the behavior of the provider.Request() method. -type RequestOpts struct { - // JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The - // content type of the request will default to "application/json" unless overridden by MoreHeaders. - // It's an error to specify both a JSONBody and a RawBody. - JSONBody interface{} - // RawBody contains an io.Reader that will be consumed by the request directly. No content-type - // will be set unless one is provided explicitly by MoreHeaders. - RawBody io.Reader - // JSONResponse, if provided, will be populated with the contents of the response body parsed as - // JSON. - JSONResponse interface{} - // OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If - // the response has a different code, an error will be returned. - OkCodes []int - // MoreHeaders specifies additional HTTP headers to be provided on the request. - // MoreHeaders will be overridden by OmitHeaders - MoreHeaders map[string]string - // OmitHeaders specifies the HTTP headers which should be omitted. - // OmitHeaders will override MoreHeaders - OmitHeaders []string - // ErrorContext specifies the resource error type to return if an error is encountered. - // This lets resources override default error messages based on the response status code. - ErrorContext error - // KeepResponseBody specifies whether to keep the HTTP response body. Usually used, when the HTTP - // response body is considered for further use. Valid when JSONResponse is nil. - KeepResponseBody bool -} - -// requestState contains temporary state for a single ProviderClient.Request() call. -type requestState struct { - // This flag indicates if we have reauthenticated during this request because of a 401 response. - // It ensures that we don't reauthenticate multiple times for a single request. If we - // reauthenticate, but keep getting 401 responses with the fresh token, reauthenticating some more - // will just get us into an infinite loop. - hasReauthenticated bool - // Retry-After backoff counter, increments during each backoff call - retries uint -} - -var applicationJSON = "application/json" - -// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication -// header will automatically be provided. -func (client *ProviderClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - return client.doRequest(method, url, options, &requestState{ - hasReauthenticated: false, - }) -} - -func (client *ProviderClient) doRequest(method, url string, options *RequestOpts, state *requestState) (*http.Response, error) { - var body io.Reader - var contentType *string - - // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided - // io.ReadSeeker as-is. Default the content-type to application/json. - if options.JSONBody != nil { - if options.RawBody != nil { - return nil, errors.New("please provide only one of JSONBody or RawBody to gophercloud.Request()") - } - - rendered, err := json.Marshal(options.JSONBody) - if err != nil { - return nil, err - } - - body = bytes.NewReader(rendered) - contentType = &applicationJSON - } - - // Return an error, when "KeepResponseBody" is true and "JSONResponse" is not nil - if options.KeepResponseBody && options.JSONResponse != nil { - return nil, errors.New("cannot use KeepResponseBody when JSONResponse is not nil") - } - - if options.RawBody != nil { - body = options.RawBody - } - - // Construct the http.Request. - req, err := http.NewRequest(method, url, body) - if err != nil { - return nil, err - } - if client.Context != nil { - req = req.WithContext(client.Context) - } - - // Populate the request headers. - // Apply options.MoreHeaders and options.OmitHeaders, to give the caller the chance to - // modify or omit any header. - if contentType != nil { - req.Header.Set("Content-Type", *contentType) - } - req.Header.Set("Accept", applicationJSON) - - // Set the User-Agent header - req.Header.Set("User-Agent", client.UserAgent.Join()) - - if options.MoreHeaders != nil { - for k, v := range options.MoreHeaders { - req.Header.Set(k, v) - } - } - - for _, v := range options.OmitHeaders { - req.Header.Del(v) - } - - // get latest token from client - for k, v := range client.AuthenticatedHeaders() { - req.Header.Set(k, v) - } - - prereqtok := req.Header.Get("X-Auth-Token") - - // Issue the request. - resp, err := client.HTTPClient.Do(req) - if err != nil { - if client.RetryFunc != nil { - var e error - state.retries = state.retries + 1 - e = client.RetryFunc(client.Context, method, url, options, err, state.retries) - if e != nil { - return nil, e - } - - return client.doRequest(method, url, options, state) - } - return nil, err - } - - // Allow default OkCodes if none explicitly set - okc := options.OkCodes - if okc == nil { - okc = defaultOkCodes(method) - } - - // Validate the HTTP response status. - var ok bool - for _, code := range okc { - if resp.StatusCode == code { - ok = true - break - } - } - - if !ok { - body, _ := ioutil.ReadAll(resp.Body) - resp.Body.Close() - respErr := ErrUnexpectedResponseCode{ - URL: url, - Method: method, - Expected: okc, - Actual: resp.StatusCode, - Body: body, - ResponseHeader: resp.Header, - } - - errType := options.ErrorContext - switch resp.StatusCode { - case http.StatusBadRequest: - err = ErrDefault400{respErr} - if error400er, ok := errType.(Err400er); ok { - err = error400er.Error400(respErr) - } - case http.StatusUnauthorized: - if client.ReauthFunc != nil && !state.hasReauthenticated { - err = client.Reauthenticate(prereqtok) - if err != nil { - e := &ErrUnableToReauthenticate{} - e.ErrOriginal = respErr - e.ErrReauth = err - return nil, e - } - if options.RawBody != nil { - if seeker, ok := options.RawBody.(io.Seeker); ok { - seeker.Seek(0, 0) - } - } - state.hasReauthenticated = true - resp, err = client.doRequest(method, url, options, state) - if err != nil { - switch err.(type) { - case *ErrUnexpectedResponseCode: - e := &ErrErrorAfterReauthentication{} - e.ErrOriginal = err.(*ErrUnexpectedResponseCode) - return nil, e - default: - e := &ErrErrorAfterReauthentication{} - e.ErrOriginal = err - return nil, e - } - } - return resp, nil - } - err = ErrDefault401{respErr} - if error401er, ok := errType.(Err401er); ok { - err = error401er.Error401(respErr) - } - case http.StatusForbidden: - err = ErrDefault403{respErr} - if error403er, ok := errType.(Err403er); ok { - err = error403er.Error403(respErr) - } - case http.StatusNotFound: - err = ErrDefault404{respErr} - if error404er, ok := errType.(Err404er); ok { - err = error404er.Error404(respErr) - } - case http.StatusMethodNotAllowed: - err = ErrDefault405{respErr} - if error405er, ok := errType.(Err405er); ok { - err = error405er.Error405(respErr) - } - case http.StatusRequestTimeout: - err = ErrDefault408{respErr} - if error408er, ok := errType.(Err408er); ok { - err = error408er.Error408(respErr) - } - case http.StatusConflict: - err = ErrDefault409{respErr} - if error409er, ok := errType.(Err409er); ok { - err = error409er.Error409(respErr) - } - case http.StatusTooManyRequests, 498: - err = ErrDefault429{respErr} - if error429er, ok := errType.(Err429er); ok { - err = error429er.Error429(respErr) - } - - maxTries := client.MaxBackoffRetries - if maxTries == 0 { - maxTries = DefaultMaxBackoffRetries - } - - if f := client.RetryBackoffFunc; f != nil && state.retries < maxTries { - var e error - - state.retries = state.retries + 1 - e = f(client.Context, &respErr, err, state.retries) - - if e != nil { - return resp, e - } - - return client.doRequest(method, url, options, state) - } - case http.StatusInternalServerError: - err = ErrDefault500{respErr} - if error500er, ok := errType.(Err500er); ok { - err = error500er.Error500(respErr) - } - case http.StatusBadGateway: - err = ErrDefault502{respErr} - if error502er, ok := errType.(Err502er); ok { - err = error502er.Error502(respErr) - } - case http.StatusServiceUnavailable: - err = ErrDefault503{respErr} - if error503er, ok := errType.(Err503er); ok { - err = error503er.Error503(respErr) - } - case http.StatusGatewayTimeout: - err = ErrDefault504{respErr} - if error504er, ok := errType.(Err504er); ok { - err = error504er.Error504(respErr) - } - } - - if err == nil { - err = respErr - } - - if err != nil && client.RetryFunc != nil { - var e error - state.retries = state.retries + 1 - e = client.RetryFunc(client.Context, method, url, options, err, state.retries) - if e != nil { - return resp, e - } - - return client.doRequest(method, url, options, state) - } - - return resp, err - } - - // Parse the response body as JSON, if requested to do so. - if options.JSONResponse != nil { - defer resp.Body.Close() - // Don't decode JSON when there is no content - if resp.StatusCode == http.StatusNoContent { - // read till EOF, otherwise the connection will be closed and cannot be reused - _, err = io.Copy(ioutil.Discard, resp.Body) - return resp, err - } - if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil { - if client.RetryFunc != nil { - var e error - state.retries = state.retries + 1 - e = client.RetryFunc(client.Context, method, url, options, err, state.retries) - if e != nil { - return resp, e - } - - return client.doRequest(method, url, options, state) - } - return nil, err - } - } - - // Close unused body to allow the HTTP connection to be reused - if !options.KeepResponseBody && options.JSONResponse == nil { - defer resp.Body.Close() - // read till EOF, otherwise the connection will be closed and cannot be reused - if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil { - return nil, err - } - } - - return resp, nil -} - -func defaultOkCodes(method string) []int { - switch method { - case "GET", "HEAD": - return []int{200} - case "POST": - return []int{201, 202} - case "PUT": - return []int{201, 202} - case "PATCH": - return []int{200, 202, 204} - case "DELETE": - return []int{202, 204} - } - - return []int{} -} diff --git a/vendor/github.com/gophercloud/gophercloud/results.go b/vendor/github.com/gophercloud/gophercloud/results.go deleted file mode 100644 index b3ee9d56..00000000 --- a/vendor/github.com/gophercloud/gophercloud/results.go +++ /dev/null @@ -1,465 +0,0 @@ -package gophercloud - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "reflect" - "strconv" - "time" -) - -/* -Result is an internal type to be used by individual resource packages, but its -methods will be available on a wide variety of user-facing embedding types. - -It acts as a base struct that other Result types, returned from request -functions, can embed for convenience. All Results capture basic information -from the HTTP transaction that was performed, including the response body, -HTTP headers, and any errors that happened. - -Generally, each Result type will have an Extract method that can be used to -further interpret the result's payload in a specific context. Extensions or -providers can then provide additional extraction functions to pull out -provider- or extension-specific information as well. -*/ -type Result struct { - // Body is the payload of the HTTP response from the server. In most cases, - // this will be the deserialized JSON structure. - Body interface{} - - // StatusCode is the HTTP status code of the original response. Will be - // one of the OkCodes defined on the gophercloud.RequestOpts that was - // used in the request. - StatusCode int - - // Header contains the HTTP header structure from the original response. - Header http.Header - - // Err is an error that occurred during the operation. It's deferred until - // extraction to make it easier to chain the Extract call. - Err error -} - -// ExtractInto allows users to provide an object into which `Extract` will extract -// the `Result.Body`. This would be useful for OpenStack providers that have -// different fields in the response object than OpenStack proper. -func (r Result) ExtractInto(to interface{}) error { - if r.Err != nil { - return r.Err - } - - if reader, ok := r.Body.(io.Reader); ok { - if readCloser, ok := reader.(io.Closer); ok { - defer readCloser.Close() - } - return json.NewDecoder(reader).Decode(to) - } - - b, err := json.Marshal(r.Body) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - return err -} - -func (r Result) extractIntoPtr(to interface{}, label string) error { - if label == "" { - return r.ExtractInto(&to) - } - - var m map[string]interface{} - err := r.ExtractInto(&m) - if err != nil { - return err - } - - b, err := json.Marshal(m[label]) - if err != nil { - return err - } - - toValue := reflect.ValueOf(to) - if toValue.Kind() == reflect.Ptr { - toValue = toValue.Elem() - } - - switch toValue.Kind() { - case reflect.Slice: - typeOfV := toValue.Type().Elem() - if typeOfV.Kind() == reflect.Struct { - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0) - - if mSlice, ok := m[label].([]interface{}); ok { - for _, v := range mSlice { - // For each iteration of the slice, we create a new struct. - // This is to work around a bug where elements of a slice - // are reused and not overwritten when the same copy of the - // struct is used: - // - // https://github.com/golang/go/issues/21092 - // https://github.com/golang/go/issues/24155 - // https://play.golang.org/p/NHo3ywlPZli - newType := reflect.New(typeOfV).Elem() - - b, err := json.Marshal(v) - if err != nil { - return err - } - - // This is needed for structs with an UnmarshalJSON method. - // Technically this is just unmarshalling the response into - // a struct that is never used, but it's good enough to - // trigger the UnmarshalJSON method. - for i := 0; i < newType.NumField(); i++ { - s := newType.Field(i).Addr().Interface() - - // Unmarshal is used rather than NewDecoder to also work - // around the above-mentioned bug. - err = json.Unmarshal(b, s) - if err != nil { - return err - } - } - - newSlice = reflect.Append(newSlice, newType) - } - } - - // "to" should now be properly modeled to receive the - // JSON response body and unmarshal into all the correct - // fields of the struct or composed extension struct - // at the end of this method. - toValue.Set(newSlice) - - // jtopjian: This was put into place to resolve the issue - // described at - // https://github.com/gophercloud/gophercloud/issues/1963 - // - // This probably isn't the best fix, but it appears to - // be resolving the issue, so I'm going to implement it - // for now. - // - // For future readers, this entire case statement could - // use a review. - return nil - } - } - case reflect.Struct: - typeOfV := toValue.Type() - if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { - for i := 0; i < toValue.NumField(); i++ { - toField := toValue.Field(i) - if toField.Kind() == reflect.Struct { - s := toField.Addr().Interface() - err = json.NewDecoder(bytes.NewReader(b)).Decode(s) - if err != nil { - return err - } - } - } - } - } - - err = json.Unmarshal(b, &to) - return err -} - -// ExtractIntoStructPtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying struct type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoStructPtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Struct: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("Expected pointer to struct, got: %v", t) - } -} - -// ExtractIntoSlicePtr will unmarshal the Result (r) into the provided -// interface{} (to). -// -// NOTE: For internal use only -// -// `to` must be a pointer to an underlying slice type -// -// If provided, `label` will be filtered out of the response -// body prior to `r` being unmarshalled into `to`. -func (r Result) ExtractIntoSlicePtr(to interface{}, label string) error { - if r.Err != nil { - return r.Err - } - - t := reflect.TypeOf(to) - if k := t.Kind(); k != reflect.Ptr { - return fmt.Errorf("Expected pointer, got %v", k) - } - switch t.Elem().Kind() { - case reflect.Slice: - return r.extractIntoPtr(to, label) - default: - return fmt.Errorf("Expected pointer to slice, got: %v", t) - } -} - -// PrettyPrintJSON creates a string containing the full response body as -// pretty-printed JSON. It's useful for capturing test fixtures and for -// debugging extraction bugs. If you include its output in an issue related to -// a buggy extraction function, we will all love you forever. -func (r Result) PrettyPrintJSON() string { - pretty, err := json.MarshalIndent(r.Body, "", " ") - if err != nil { - panic(err.Error()) - } - return string(pretty) -} - -// ErrResult is an internal type to be used by individual resource packages, but -// its methods will be available on a wide variety of user-facing embedding -// types. -// -// It represents results that only contain a potential error and -// nothing else. Usually, if the operation executed successfully, the Err field -// will be nil; otherwise it will be stocked with a relevant error. Use the -// ExtractErr method -// to cleanly pull it out. -type ErrResult struct { - Result -} - -// ExtractErr is a function that extracts error information, or nil, from a result. -func (r ErrResult) ExtractErr() error { - return r.Err -} - -/* -HeaderResult is an internal type to be used by individual resource packages, but -its methods will be available on a wide variety of user-facing embedding types. - -It represents a result that only contains an error (possibly nil) and an -http.Header. This is used, for example, by the objectstorage packages in -openstack, because most of the operations don't return response bodies, but do -have relevant information in headers. -*/ -type HeaderResult struct { - Result -} - -// ExtractInto allows users to provide an object into which `Extract` will -// extract the http.Header headers of the result. -func (r HeaderResult) ExtractInto(to interface{}) error { - if r.Err != nil { - return r.Err - } - - tmpHeaderMap := map[string]string{} - for k, v := range r.Header { - if len(v) > 0 { - tmpHeaderMap[k] = v[0] - } - } - - b, err := json.Marshal(tmpHeaderMap) - if err != nil { - return err - } - err = json.Unmarshal(b, to) - - return err -} - -// RFC3339Milli describes a common time format used by some API responses. -const RFC3339Milli = "2006-01-02T15:04:05.999999Z" - -type JSONRFC3339Milli time.Time - -func (jt *JSONRFC3339Milli) UnmarshalJSON(data []byte) error { - b := bytes.NewBuffer(data) - dec := json.NewDecoder(b) - var s string - if err := dec.Decode(&s); err != nil { - return err - } - t, err := time.Parse(RFC3339Milli, s) - if err != nil { - return err - } - *jt = JSONRFC3339Milli(t) - return nil -} - -const RFC3339MilliNoZ = "2006-01-02T15:04:05.999999" - -type JSONRFC3339MilliNoZ time.Time - -func (jt *JSONRFC3339MilliNoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339MilliNoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339MilliNoZ(t) - return nil -} - -type JSONRFC1123 time.Time - -func (jt *JSONRFC1123) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(time.RFC1123, s) - if err != nil { - return err - } - *jt = JSONRFC1123(t) - return nil -} - -type JSONUnix time.Time - -func (jt *JSONUnix) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - unix, err := strconv.ParseInt(s, 10, 64) - if err != nil { - return err - } - t = time.Unix(unix, 0) - *jt = JSONUnix(t) - return nil -} - -// RFC3339NoZ is the time format used in Heat (Orchestration). -const RFC3339NoZ = "2006-01-02T15:04:05" - -type JSONRFC3339NoZ time.Time - -func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339NoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339NoZ(t) - return nil -} - -// RFC3339ZNoT is the time format used in Zun (Containers Service). -const RFC3339ZNoT = "2006-01-02 15:04:05-07:00" - -type JSONRFC3339ZNoT time.Time - -func (jt *JSONRFC3339ZNoT) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339ZNoT, s) - if err != nil { - return err - } - *jt = JSONRFC3339ZNoT(t) - return nil -} - -// RFC3339ZNoTNoZ is another time format used in Zun (Containers Service). -const RFC3339ZNoTNoZ = "2006-01-02 15:04:05" - -type JSONRFC3339ZNoTNoZ time.Time - -func (jt *JSONRFC3339ZNoTNoZ) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return err - } - if s == "" { - return nil - } - t, err := time.Parse(RFC3339ZNoTNoZ, s) - if err != nil { - return err - } - *jt = JSONRFC3339ZNoTNoZ(t) - return nil -} - -/* -Link is an internal type to be used in packages of collection resources that are -paginated in a certain way. - -It's a response substructure common to many paginated collection results that is -used to point to related pages. Usually, the one we care about is the one with -Rel field set to "next". -*/ -type Link struct { - Href string `json:"href"` - Rel string `json:"rel"` -} - -/* -ExtractNextURL is an internal function useful for packages of collection -resources that are paginated in a certain way. - -It attempts to extract the "next" URL from slice of Link structs, or -"" if no such URL is present. -*/ -func ExtractNextURL(links []Link) (string, error) { - var url string - - for _, l := range links { - if l.Rel == "next" { - url = l.Href - } - } - - if url == "" { - return "", nil - } - - return url, nil -} diff --git a/vendor/github.com/gophercloud/gophercloud/service_client.go b/vendor/github.com/gophercloud/gophercloud/service_client.go deleted file mode 100644 index 94a161e3..00000000 --- a/vendor/github.com/gophercloud/gophercloud/service_client.go +++ /dev/null @@ -1,163 +0,0 @@ -package gophercloud - -import ( - "io" - "net/http" - "strings" -) - -// ServiceClient stores details required to interact with a specific service API implemented by a provider. -// Generally, you'll acquire these by calling the appropriate `New` method on a ProviderClient. -type ServiceClient struct { - // ProviderClient is a reference to the provider that implements this service. - *ProviderClient - - // Endpoint is the base URL of the service's API, acquired from a service catalog. - // It MUST end with a /. - Endpoint string - - // ResourceBase is the base URL shared by the resources within a service's API. It should include - // the API version and, like Endpoint, MUST end with a / if set. If not set, the Endpoint is used - // as-is, instead. - ResourceBase string - - // This is the service client type (e.g. compute, sharev2). - // NOTE: FOR INTERNAL USE ONLY. DO NOT SET. GOPHERCLOUD WILL SET THIS. - // It is only exported because it gets set in a different package. - Type string - - // The microversion of the service to use. Set this to use a particular microversion. - Microversion string - - // MoreHeaders allows users (or Gophercloud) to set service-wide headers on requests. Put another way, - // values set in this field will be set on all the HTTP requests the service client sends. - MoreHeaders map[string]string -} - -// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /. -func (client *ServiceClient) ResourceBaseURL() string { - if client.ResourceBase != "" { - return client.ResourceBase - } - return client.Endpoint -} - -// ServiceURL constructs a URL for a resource belonging to this provider. -func (client *ServiceClient) ServiceURL(parts ...string) string { - return client.ResourceBaseURL() + strings.Join(parts, "/") -} - -func (client *ServiceClient) initReqOpts(JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) { - if v, ok := (JSONBody).(io.Reader); ok { - opts.RawBody = v - } else if JSONBody != nil { - opts.JSONBody = JSONBody - } - - if JSONResponse != nil { - opts.JSONResponse = JSONResponse - } -} - -// Get calls `Request` with the "GET" HTTP verb. -func (client *ServiceClient) Get(url string, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(nil, JSONResponse, opts) - return client.Request("GET", url, opts) -} - -// Post calls `Request` with the "POST" HTTP verb. -func (client *ServiceClient) Post(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(JSONBody, JSONResponse, opts) - return client.Request("POST", url, opts) -} - -// Put calls `Request` with the "PUT" HTTP verb. -func (client *ServiceClient) Put(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(JSONBody, JSONResponse, opts) - return client.Request("PUT", url, opts) -} - -// Patch calls `Request` with the "PATCH" HTTP verb. -func (client *ServiceClient) Patch(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(JSONBody, JSONResponse, opts) - return client.Request("PATCH", url, opts) -} - -// Delete calls `Request` with the "DELETE" HTTP verb. -func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(nil, nil, opts) - return client.Request("DELETE", url, opts) -} - -// Head calls `Request` with the "HEAD" HTTP verb. -func (client *ServiceClient) Head(url string, opts *RequestOpts) (*http.Response, error) { - if opts == nil { - opts = new(RequestOpts) - } - client.initReqOpts(nil, nil, opts) - return client.Request("HEAD", url, opts) -} - -func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { - switch client.Type { - case "compute": - opts.MoreHeaders["X-OpenStack-Nova-API-Version"] = client.Microversion - case "sharev2": - opts.MoreHeaders["X-OpenStack-Manila-API-Version"] = client.Microversion - case "volume": - opts.MoreHeaders["X-OpenStack-Volume-API-Version"] = client.Microversion - case "baremetal": - opts.MoreHeaders["X-OpenStack-Ironic-API-Version"] = client.Microversion - case "baremetal-introspection": - opts.MoreHeaders["X-OpenStack-Ironic-Inspector-API-Version"] = client.Microversion - } - - if client.Type != "" { - opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion - } -} - -// Request carries out the HTTP operation for the service client -func (client *ServiceClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { - if options.MoreHeaders == nil { - options.MoreHeaders = make(map[string]string) - } - - if client.Microversion != "" { - client.setMicroversionHeader(options) - } - - if len(client.MoreHeaders) > 0 { - if options == nil { - options = new(RequestOpts) - } - - for k, v := range client.MoreHeaders { - options.MoreHeaders[k] = v - } - } - return client.ProviderClient.Request(method, url, options) -} - -// ParseResponse is a helper function to parse http.Response to constituents. -func ParseResponse(resp *http.Response, err error) (io.ReadCloser, http.Header, error) { - if resp != nil { - return resp.Body, resp.Header, err - } - return nil, nil, err -} diff --git a/vendor/github.com/gophercloud/gophercloud/util.go b/vendor/github.com/gophercloud/gophercloud/util.go deleted file mode 100644 index 2740c301..00000000 --- a/vendor/github.com/gophercloud/gophercloud/util.go +++ /dev/null @@ -1,130 +0,0 @@ -package gophercloud - -import ( - "fmt" - "net/url" - "path/filepath" - "reflect" - "strings" - "time" -) - -// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as -// a reference in the filesystem, if necessary. basePath is assumed to contain -// either '.' when first used, or the file:// type fqdn of the parent resource. -// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml -func NormalizePathURL(basePath, rawPath string) (string, error) { - u, err := url.Parse(rawPath) - if err != nil { - return "", err - } - // if a scheme is defined, it must be a fqdn already - if u.Scheme != "" { - return u.String(), nil - } - // if basePath is a url, then child resources are assumed to be relative to it - bu, err := url.Parse(basePath) - if err != nil { - return "", err - } - var basePathSys, absPathSys string - if bu.Scheme != "" { - basePathSys = filepath.FromSlash(bu.Path) - absPathSys = filepath.Join(basePathSys, rawPath) - bu.Path = filepath.ToSlash(absPathSys) - return bu.String(), nil - } - - absPathSys = filepath.Join(basePath, rawPath) - u.Path = filepath.ToSlash(absPathSys) - if err != nil { - return "", err - } - u.Scheme = "file" - return u.String(), nil -} - -// NormalizeURL is an internal function to be used by provider clients. -// -// It ensures that each endpoint URL has a closing `/`, as expected by -// ServiceClient's methods. -func NormalizeURL(url string) string { - if !strings.HasSuffix(url, "/") { - return url + "/" - } - return url -} - -// RemainingKeys will inspect a struct and compare it to a map. Any struct -// field that does not have a JSON tag that matches a key in the map or -// a matching lower-case field in the map will be returned as an extra. -// -// This is useful for determining the extra fields returned in response bodies -// for resources that can contain an arbitrary or dynamic number of fields. -func RemainingKeys(s interface{}, m map[string]interface{}) (extras map[string]interface{}) { - extras = make(map[string]interface{}) - for k, v := range m { - extras[k] = v - } - - valueOf := reflect.ValueOf(s) - typeOf := reflect.TypeOf(s) - for i := 0; i < valueOf.NumField(); i++ { - field := typeOf.Field(i) - - lowerField := strings.ToLower(field.Name) - delete(extras, lowerField) - - if tagValue := field.Tag.Get("json"); tagValue != "" && tagValue != "-" { - delete(extras, tagValue) - } - } - - return -} - -// WaitFor polls a predicate function, once per second, up to a timeout limit. -// This is useful to wait for a resource to transition to a certain state. -// To handle situations when the predicate might hang indefinitely, the -// predicate will be prematurely cancelled after the timeout. -// Resource packages will wrap this in a more convenient function that's -// specific to a certain resource, but it can also be useful on its own. -func WaitFor(timeout int, predicate func() (bool, error)) error { - type WaitForResult struct { - Success bool - Error error - } - - start := time.Now().Unix() - - for { - // If a timeout is set, and that's been exceeded, shut it down. - if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) { - return fmt.Errorf("A timeout occurred") - } - - time.Sleep(1 * time.Second) - - var result WaitForResult - ch := make(chan bool, 1) - go func() { - defer close(ch) - satisfied, err := predicate() - result.Success = satisfied - result.Error = err - }() - - select { - case <-ch: - if result.Error != nil { - return result.Error - } - if result.Success { - return nil - } - // If the predicate has not finished by the timeout, cancel it. - case <-time.After(time.Duration(timeout) * time.Second): - return fmt.Errorf("A timeout occurred") - } - } -} diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md index 6f105f1a..afc55af9 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,3 +1,10 @@ +## 2.20.2 + +Require Go 1.22+ + +### Maintenance +- bump go to v1.22 [a671816] + ## 2.20.1 ### Fixes diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index 58fddc09..6dfb25f2 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.20.1" +const VERSION = "2.20.2" diff --git a/vendor/k8s.io/apimachinery/pkg/api/apitesting/codec.go b/vendor/k8s.io/apimachinery/pkg/api/apitesting/codec.go new file mode 100644 index 00000000..542b0aa2 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/apitesting/codec.go @@ -0,0 +1,116 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apitesting + +import ( + "fmt" + "mime" + "os" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/runtime/serializer/recognizer" +) + +var ( + testCodecMediaType string + testStorageCodecMediaType string +) + +// TestCodec returns the codec for the API version to test against, as set by the +// KUBE_TEST_API_TYPE env var. +func TestCodec(codecs runtimeserializer.CodecFactory, gvs ...schema.GroupVersion) runtime.Codec { + if len(testCodecMediaType) != 0 { + serializerInfo, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), testCodecMediaType) + if !ok { + panic(fmt.Sprintf("no serializer for %s", testCodecMediaType)) + } + return codecs.CodecForVersions(serializerInfo.Serializer, codecs.UniversalDeserializer(), schema.GroupVersions(gvs), nil) + } + return codecs.LegacyCodec(gvs...) +} + +// TestStorageCodec returns the codec for the API version to test against used in storage, as set by the +// KUBE_TEST_API_STORAGE_TYPE env var. +func TestStorageCodec(codecs runtimeserializer.CodecFactory, gvs ...schema.GroupVersion) runtime.Codec { + if len(testStorageCodecMediaType) != 0 { + serializerInfo, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), testStorageCodecMediaType) + if !ok { + panic(fmt.Sprintf("no serializer for %s", testStorageCodecMediaType)) + } + + // etcd2 only supports string data - we must wrap any result before returning + // TODO: remove for etcd3 / make parameterizable + serializer := serializerInfo.Serializer + if !serializerInfo.EncodesAsText { + serializer = runtime.NewBase64Serializer(serializer, serializer) + } + + decoder := recognizer.NewDecoder(serializer, codecs.UniversalDeserializer()) + return codecs.CodecForVersions(serializer, decoder, schema.GroupVersions(gvs), nil) + + } + return codecs.LegacyCodec(gvs...) +} + +func init() { + var err error + if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 { + testCodecMediaType, _, err = mime.ParseMediaType(apiMediaType) + if err != nil { + panic(err) + } + } + + if storageMediaType := os.Getenv("KUBE_TEST_API_STORAGE_TYPE"); len(storageMediaType) > 0 { + testStorageCodecMediaType, _, err = mime.ParseMediaType(storageMediaType) + if err != nil { + panic(err) + } + } +} + +// InstallOrDieFunc mirrors install functions that require success +type InstallOrDieFunc func(scheme *runtime.Scheme) + +// SchemeForInstallOrDie builds a simple test scheme and codecfactory pair for easy unit testing from higher level install methods +func SchemeForInstallOrDie(installFns ...InstallOrDieFunc) (*runtime.Scheme, runtimeserializer.CodecFactory) { + scheme := runtime.NewScheme() + codecFactory := runtimeserializer.NewCodecFactory(scheme) + for _, installFn := range installFns { + installFn(scheme) + } + + return scheme, codecFactory +} + +// InstallFunc mirrors install functions that can return an error +type InstallFunc func(scheme *runtime.Scheme) error + +// SchemeForOrDie builds a simple test scheme and codecfactory pair for easy unit testing from the bare registration methods. +func SchemeForOrDie(installFns ...InstallFunc) (*runtime.Scheme, runtimeserializer.CodecFactory) { + scheme := runtime.NewScheme() + codecFactory := runtimeserializer.NewCodecFactory(scheme) + for _, installFn := range installFns { + if err := installFn(scheme); err != nil { + panic(err) + } + } + + return scheme, codecFactory +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/fuzzer.go b/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/fuzzer.go new file mode 100644 index 00000000..f528e9f9 --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/fuzzer.go @@ -0,0 +1,52 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fuzzer + +import ( + "math/rand" + + "github.com/google/gofuzz" + + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" +) + +// FuzzerFuncs returns a list of func(*SomeType, c fuzz.Continue) functions. +type FuzzerFuncs func(codecs runtimeserializer.CodecFactory) []interface{} + +// FuzzerFor can randomly populate api objects that are destined for version. +func FuzzerFor(funcs FuzzerFuncs, src rand.Source, codecs runtimeserializer.CodecFactory) *fuzz.Fuzzer { + f := fuzz.New().NilChance(.5).NumElements(0, 1) + if src != nil { + f.RandSource(src) + } + f.Funcs(funcs(codecs)...) + return f +} + +// MergeFuzzerFuncs will merge the given funcLists, overriding early funcs with later ones if there first +// argument has the same type. +func MergeFuzzerFuncs(funcs ...FuzzerFuncs) FuzzerFuncs { + return FuzzerFuncs(func(codecs runtimeserializer.CodecFactory) []interface{} { + result := []interface{}{} + for _, f := range funcs { + if f != nil { + result = append(result, f(codecs)...) + } + } + return result + }) +} diff --git a/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/valuefuzz.go b/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/valuefuzz.go new file mode 100644 index 00000000..facff57b --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/api/apitesting/fuzzer/valuefuzz.go @@ -0,0 +1,86 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fuzzer + +import ( + "reflect" +) + +// ValueFuzz recursively changes all basic type values in an object. Any kind of references will not +// be touch, i.e. the addresses of slices, maps, pointers will stay unchanged. +func ValueFuzz(obj interface{}) { + valueFuzz(reflect.ValueOf(obj)) +} + +func valueFuzz(obj reflect.Value) { + switch obj.Kind() { + case reflect.Array: + for i := 0; i < obj.Len(); i++ { + valueFuzz(obj.Index(i)) + } + case reflect.Slice: + if obj.IsNil() { + // TODO: set non-nil value + } else { + for i := 0; i < obj.Len(); i++ { + valueFuzz(obj.Index(i)) + } + } + case reflect.Interface, reflect.Pointer: + if obj.IsNil() { + // TODO: set non-nil value + } else { + valueFuzz(obj.Elem()) + } + case reflect.Struct: + for i, n := 0, obj.NumField(); i < n; i++ { + valueFuzz(obj.Field(i)) + } + case reflect.Map: + if obj.IsNil() { + // TODO: set non-nil value + } else { + for _, k := range obj.MapKeys() { + // map values are not addressable. We need a copy. + v := obj.MapIndex(k) + copy := reflect.New(v.Type()) + copy.Elem().Set(v) + valueFuzz(copy.Elem()) + obj.SetMapIndex(k, copy.Elem()) + } + // TODO: set some new value + } + case reflect.Func: // ignore, we don't have function types in our API + default: + if !obj.CanSet() { + return + } + switch obj.Kind() { + case reflect.String: + obj.SetString(obj.String() + "x") + case reflect.Bool: + obj.SetBool(!obj.Bool()) + case reflect.Float32, reflect.Float64: + obj.SetFloat(obj.Float()*2.0 + 1.0) + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + obj.SetInt(obj.Int() + 1) + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + obj.SetUint(obj.Uint() + 1) + default: + } + } +} diff --git a/vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go b/vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go new file mode 100644 index 00000000..6bc1356e --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer/fuzzer.go @@ -0,0 +1,337 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fuzzer + +import ( + "fmt" + "math/rand" + "sort" + "strconv" + "strings" + + fuzz "github.com/google/gofuzz" + + apitesting "k8s.io/apimachinery/pkg/api/apitesting" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/types" +) + +func genericFuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(q *resource.Quantity, c fuzz.Continue) { + *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) + }, + func(j *int, c fuzz.Continue) { + *j = int(c.Int31()) + }, + func(j **int, c fuzz.Continue) { + if c.RandBool() { + i := int(c.Int31()) + *j = &i + } else { + *j = nil + } + }, + func(j *runtime.TypeMeta, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = "" + j.Kind = "" + }, + func(j *runtime.Object, c fuzz.Continue) { + // TODO: uncomment when round trip starts from a versioned object + if true { //c.RandBool() { + *j = &runtime.Unknown{ + // We do not set TypeMeta here because it is not carried through a round trip + Raw: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`), + ContentType: runtime.ContentTypeJSON, + } + } else { + types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}} + t := types[c.Rand.Intn(len(types))] + c.Fuzz(t) + *j = t + } + }, + func(r *runtime.RawExtension, c fuzz.Continue) { + // Pick an arbitrary type and fuzz it + types := []runtime.Object{&metav1.Status{}, &metav1.APIGroup{}} + obj := types[c.Rand.Intn(len(types))] + c.Fuzz(obj) + + // Find a codec for converting the object to raw bytes. This is necessary for the + // api version and kind to be correctly set be serialization. + var codec = apitesting.TestCodec(codecs, metav1.SchemeGroupVersion) + + // Convert the object to raw bytes + bytes, err := runtime.Encode(codec, obj) + if err != nil { + panic(fmt.Sprintf("Failed to encode object: %v", err)) + } + + // strip trailing newlines which do not survive roundtrips + for len(bytes) >= 1 && bytes[len(bytes)-1] == 10 { + bytes = bytes[:len(bytes)-1] + } + + // Set the bytes field on the RawExtension + r.Raw = bytes + }, + } +} + +// taken from gofuzz internals for RandString +type charRange struct { + first, last rune +} + +func (c *charRange) choose(r *rand.Rand) rune { + count := int64(c.last - c.first + 1) + ch := c.first + rune(r.Int63n(count)) + + return ch +} + +// randomLabelPart produces a valid random label value or name-part +// of a label key. +func randomLabelPart(c fuzz.Continue, canBeEmpty bool) string { + validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}} + validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'A', 'Z'}, + {'.', '.'}, {'-', '-'}, {'_', '_'}} + + partLen := c.Rand.Intn(64) // len is [0, 63] + if !canBeEmpty { + partLen = c.Rand.Intn(63) + 1 // len is [1, 63] + } + + runes := make([]rune, partLen) + if partLen == 0 { + return string(runes) + } + + runes[0] = validStartEnd[c.Rand.Intn(len(validStartEnd))].choose(c.Rand) + for i := range runes[1:] { + runes[i+1] = validMiddle[c.Rand.Intn(len(validMiddle))].choose(c.Rand) + } + runes[len(runes)-1] = validStartEnd[c.Rand.Intn(len(validStartEnd))].choose(c.Rand) + + return string(runes) +} + +func randomDNSLabel(c fuzz.Continue) string { + validStartEnd := []charRange{{'0', '9'}, {'a', 'z'}} + validMiddle := []charRange{{'0', '9'}, {'a', 'z'}, {'-', '-'}} + + partLen := c.Rand.Intn(63) + 1 // len is [1, 63] + runes := make([]rune, partLen) + + runes[0] = validStartEnd[c.Rand.Intn(len(validStartEnd))].choose(c.Rand) + for i := range runes[1:] { + runes[i+1] = validMiddle[c.Rand.Intn(len(validMiddle))].choose(c.Rand) + } + runes[len(runes)-1] = validStartEnd[c.Rand.Intn(len(validStartEnd))].choose(c.Rand) + + return string(runes) +} + +func randomLabelKey(c fuzz.Continue) string { + namePart := randomLabelPart(c, false) + prefixPart := "" + + usePrefix := c.RandBool() + if usePrefix { + // we can fit, with dots, at most 3 labels in the 253 allotted characters + prefixPartsLen := c.Rand.Intn(2) + 1 + prefixParts := make([]string, prefixPartsLen) + for i := range prefixParts { + prefixParts[i] = randomDNSLabel(c) + } + prefixPart = strings.Join(prefixParts, ".") + "/" + } + + return prefixPart + namePart +} + +func v1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { + + return []interface{}{ + func(j *metav1.TypeMeta, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = "" + j.Kind = "" + }, + func(j *metav1.ObjectMeta, c fuzz.Continue) { + c.FuzzNoCustom(j) + + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.UID = types.UID(c.RandString()) + + // Fuzzing sec and nsec in a smaller range (uint32 instead of int64), + // so that the result Unix time is a valid date and can be parsed into RFC3339 format. + var sec, nsec uint32 + c.Fuzz(&sec) + c.Fuzz(&nsec) + j.CreationTimestamp = metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy() + + if j.DeletionTimestamp != nil { + c.Fuzz(&sec) + c.Fuzz(&nsec) + t := metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy() + j.DeletionTimestamp = &t + } + + if len(j.Labels) == 0 { + j.Labels = nil + } else { + delete(j.Labels, "") + } + if len(j.Annotations) == 0 { + j.Annotations = nil + } else { + delete(j.Annotations, "") + } + if len(j.OwnerReferences) == 0 { + j.OwnerReferences = nil + } + if len(j.Finalizers) == 0 { + j.Finalizers = nil + } + }, + func(j *metav1.ResourceVersionMatch, c fuzz.Continue) { + matches := []metav1.ResourceVersionMatch{"", metav1.ResourceVersionMatchExact, metav1.ResourceVersionMatchNotOlderThan} + *j = matches[c.Rand.Intn(len(matches))] + }, + func(j *metav1.ListMeta, c fuzz.Continue) { + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.SelfLink = c.RandString() + }, + func(j *metav1.LabelSelector, c fuzz.Continue) { + c.FuzzNoCustom(j) + // we can't have an entirely empty selector, so force + // use of MatchExpression if necessary + if len(j.MatchLabels) == 0 && len(j.MatchExpressions) == 0 { + j.MatchExpressions = make([]metav1.LabelSelectorRequirement, c.Rand.Intn(2)+1) + } + + if j.MatchLabels != nil { + fuzzedMatchLabels := make(map[string]string, len(j.MatchLabels)) + for i := 0; i < len(j.MatchLabels); i++ { + fuzzedMatchLabels[randomLabelKey(c)] = randomLabelPart(c, true) + } + j.MatchLabels = fuzzedMatchLabels + } + + validOperators := []metav1.LabelSelectorOperator{ + metav1.LabelSelectorOpIn, + metav1.LabelSelectorOpNotIn, + metav1.LabelSelectorOpExists, + metav1.LabelSelectorOpDoesNotExist, + } + + if j.MatchExpressions != nil { + // NB: the label selector parser code sorts match expressions by key, and sorts the values, + // so we need to make sure ours are sorted as well here to preserve round-trip comparison. + // In practice, not sorting doesn't hurt anything... + + for i := range j.MatchExpressions { + req := metav1.LabelSelectorRequirement{} + c.Fuzz(&req) + req.Key = randomLabelKey(c) + req.Operator = validOperators[c.Rand.Intn(len(validOperators))] + if req.Operator == metav1.LabelSelectorOpIn || req.Operator == metav1.LabelSelectorOpNotIn { + if len(req.Values) == 0 { + // we must have some values here, so randomly choose a short length + req.Values = make([]string, c.Rand.Intn(2)+1) + } + for i := range req.Values { + req.Values[i] = randomLabelPart(c, true) + } + sort.Strings(req.Values) + } else { + req.Values = nil + } + j.MatchExpressions[i] = req + } + + sort.Slice(j.MatchExpressions, func(a, b int) bool { return j.MatchExpressions[a].Key < j.MatchExpressions[b].Key }) + } + }, + func(j *metav1.ManagedFieldsEntry, c fuzz.Continue) { + c.FuzzNoCustom(j) + j.FieldsV1 = nil + }, + } +} + +func v1beta1FuzzerFuncs(codecs runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + func(r *metav1beta1.TableOptions, c fuzz.Continue) { + c.FuzzNoCustom(r) + // NoHeaders is not serialized to the wire but is allowed within the versioned + // type because we don't use meta internal types in the client and API server. + r.NoHeaders = false + }, + func(r *metav1beta1.TableRow, c fuzz.Continue) { + c.Fuzz(&r.Object) + c.Fuzz(&r.Conditions) + if len(r.Conditions) == 0 { + r.Conditions = nil + } + n := c.Intn(10) + if n > 0 { + r.Cells = make([]interface{}, n) + } + for i := range r.Cells { + t := c.Intn(6) + switch t { + case 0: + r.Cells[i] = c.RandString() + case 1: + r.Cells[i] = c.Int63() + case 2: + r.Cells[i] = c.RandBool() + case 3: + x := map[string]interface{}{} + for j := c.Intn(10) + 1; j >= 0; j-- { + x[c.RandString()] = c.RandString() + } + r.Cells[i] = x + case 4: + x := make([]interface{}, c.Intn(10)) + for i := range x { + x[i] = c.Int63() + } + r.Cells[i] = x + default: + r.Cells[i] = nil + } + } + }, + } +} + +var Funcs = fuzzer.MergeFuzzerFuncs( + genericFuzzerFuncs, + v1FuzzerFuncs, + v1beta1FuzzerFuncs, +) diff --git a/vendor/github.com/gophercloud/gophercloud/LICENSE b/vendor/k8s.io/kubernetes/LICENSE similarity index 89% rename from vendor/github.com/gophercloud/gophercloud/LICENSE rename to vendor/k8s.io/kubernetes/LICENSE index c3f4f2f7..d6456956 100644 --- a/vendor/github.com/gophercloud/gophercloud/LICENSE +++ b/vendor/k8s.io/kubernetes/LICENSE @@ -1,20 +1,5 @@ -Copyright 2012-2013 Rackspace, Inc. -Copyright Gophercloud authors -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. - ------- - - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -190,3 +175,28 @@ specific language governing permissions and limitations under the License. of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinelist_webhook.go b/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go similarity index 50% rename from vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinelist_webhook.go rename to vendor/k8s.io/kubernetes/pkg/util/hash/hash.go index 0122e1b5..0962e5cf 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinelist_webhook.go +++ b/vendor/k8s.io/kubernetes/pkg/util/hash/hash.go @@ -1,11 +1,11 @@ /* -Copyright 2023 The Kubernetes Authors. +Copyright 2015 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -14,19 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha7 +package hash import ( - "sigs.k8s.io/controller-runtime/pkg/builder" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" -) + "fmt" + "hash" -// log is for logging in this package. -var _ = logf.Log.WithName("openstackmachinelist-resource") + "k8s.io/apimachinery/pkg/util/dump" +) -func (r *OpenStackMachineList) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(r). - Complete() +// DeepHashObject writes specified object to hash using the spew library +// which follows pointers and prints actual values of the nested objects +// ensuring the hash does not change when a pointer changes. +func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { + hasher.Reset() + fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite)) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 518975e4..b93c8af1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -141,15 +141,6 @@ github.com/google/pprof/profile # github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid -# github.com/gophercloud/gophercloud v1.11.0 -## explicit; go 1.14 -github.com/gophercloud/gophercloud -github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers -github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups -github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules -github.com/gophercloud/gophercloud/openstack/networking/v2/networks -github.com/gophercloud/gophercloud/openstack/networking/v2/subnets -github.com/gophercloud/gophercloud/pagination # github.com/gophercloud/gophercloud/v2 v2.1.0 ## explicit; go 1.22 github.com/gophercloud/gophercloud/v2 @@ -197,8 +188,8 @@ github.com/modern-go/reflect2 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/onsi/ginkgo/v2 v2.20.1 -## explicit; go 1.20 +# github.com/onsi/ginkgo/v2 v2.20.2 +## explicit; go 1.22 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config github.com/onsi/ginkgo/v2/formatter @@ -477,11 +468,14 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextension k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 # k8s.io/apimachinery v0.30.3 ## explicit; go 1.22.0 +k8s.io/apimachinery/pkg/api/apitesting +k8s.io/apimachinery/pkg/api/apitesting/fuzzer k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors k8s.io/apimachinery/pkg/api/meta k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/api/validation +k8s.io/apimachinery/pkg/apis/meta/fuzzer k8s.io/apimachinery/pkg/apis/meta/internalversion k8s.io/apimachinery/pkg/apis/meta/internalversion/scheme k8s.io/apimachinery/pkg/apis/meta/v1 @@ -696,6 +690,9 @@ k8s.io/kube-openapi/pkg/schemaconv k8s.io/kube-openapi/pkg/spec3 k8s.io/kube-openapi/pkg/util/proto k8s.io/kube-openapi/pkg/validation/spec +# k8s.io/kubernetes v1.28.3 +## explicit; go 1.20 +k8s.io/kubernetes/pkg/util/hash # k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 ## explicit; go 1.18 k8s.io/utils/buffer @@ -744,13 +741,17 @@ sigs.k8s.io/cluster-api/util sigs.k8s.io/cluster-api/util/annotations sigs.k8s.io/cluster-api/util/conditions sigs.k8s.io/cluster-api/util/contract +sigs.k8s.io/cluster-api/util/conversion sigs.k8s.io/cluster-api/util/labels/format sigs.k8s.io/cluster-api/util/patch sigs.k8s.io/cluster-api/util/record -sigs.k8s.io/cluster-api/util/topology -# sigs.k8s.io/cluster-api-provider-openstack v0.9.2 -## explicit; go 1.20 +# sigs.k8s.io/cluster-api-provider-openstack v0.10.5 +## explicit; go 1.22 sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7 +sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1 +sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion +sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon +sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional # sigs.k8s.io/controller-runtime v0.18.5 ## explicit; go 1.22.0 sigs.k8s.io/controller-runtime diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/conversion.go deleted file mode 100644 index 4bbb9d0e..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/conversion.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -// Hub marks OpenStackCluster as a conversion hub. -func (*OpenStackCluster) Hub() {} - -// Hub marks OpenStackClusterList as a conversion hub. -func (*OpenStackClusterList) Hub() {} - -// Hub marks OpenStackClusterTemplate as a conversion hub. -func (*OpenStackClusterTemplate) Hub() {} - -// Hub marks OpenStackClusterTemplateList as a conversion hub. -func (*OpenStackClusterTemplateList) Hub() {} - -// Hub marks OpenStackMachine as a conversion hub. -func (*OpenStackMachine) Hub() {} - -// Hub marks OpenStackMachineList as a conversion hub. -func (*OpenStackMachineList) Hub() {} - -// Hub marks OpenStackMachineTemplate as a conversion hub. -func (*OpenStackMachineTemplate) Hub() {} - -// Hub marks OpenStackMachineTemplateList as a conversion hub. -func (*OpenStackMachineTemplateList) Hub() {} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/doc.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/doc.go index 817c2b41..0c61ce4c 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/doc.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/doc.go @@ -14,4 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +// Package v1alpha7 contains API Schema definitions for the infrastructure v1alpha7 API group. +// +kubebuilder:object:generate=true +// +groupName=infrastructure.cluster.x-k8s.io +// +k8s:conversion-gen=sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1 package v1alpha7 diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/filter_convert.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/filter_convert.go deleted file mode 100644 index 236c91fc..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/filter_convert.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers" - securitygroups "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups" - "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" - "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets" -) - -func (securityGroupFilter SecurityGroupFilter) ToListOpt() securitygroups.ListOpts { - return securitygroups.ListOpts{ - ID: securityGroupFilter.ID, - Name: securityGroupFilter.Name, - Description: securityGroupFilter.Description, - ProjectID: securityGroupFilter.ProjectID, - Tags: securityGroupFilter.Tags, - TagsAny: securityGroupFilter.TagsAny, - NotTags: securityGroupFilter.NotTags, - NotTagsAny: securityGroupFilter.NotTagsAny, - } -} - -func (subnetFilter SubnetFilter) ToListOpt() subnets.ListOpts { - return subnets.ListOpts{ - Name: subnetFilter.Name, - Description: subnetFilter.Description, - ProjectID: subnetFilter.ProjectID, - IPVersion: subnetFilter.IPVersion, - GatewayIP: subnetFilter.GatewayIP, - CIDR: subnetFilter.CIDR, - IPv6AddressMode: subnetFilter.IPv6AddressMode, - IPv6RAMode: subnetFilter.IPv6RAMode, - ID: subnetFilter.ID, - Tags: subnetFilter.Tags, - TagsAny: subnetFilter.TagsAny, - NotTags: subnetFilter.NotTags, - NotTagsAny: subnetFilter.NotTagsAny, - } -} - -func (networkFilter NetworkFilter) ToListOpt() networks.ListOpts { - return networks.ListOpts{ - Name: networkFilter.Name, - Description: networkFilter.Description, - ProjectID: networkFilter.ProjectID, - ID: networkFilter.ID, - Tags: networkFilter.Tags, - TagsAny: networkFilter.TagsAny, - NotTags: networkFilter.NotTags, - NotTagsAny: networkFilter.NotTagsAny, - } -} - -func (routerFilter RouterFilter) ToListOpt() routers.ListOpts { - return routers.ListOpts{ - ID: routerFilter.ID, - Name: routerFilter.Name, - Description: routerFilter.Description, - ProjectID: routerFilter.ProjectID, - Tags: routerFilter.Tags, - TagsAny: routerFilter.TagsAny, - NotTags: routerFilter.NotTags, - NotTagsAny: routerFilter.NotTagsAny, - } -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/groupversion_info.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/groupversion_info.go index 019caf4f..e3aadf9f 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/groupversion_info.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/groupversion_info.go @@ -14,9 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// package v1alpha7 contains API Schema definitions for the infrastructure v1alpha7 API group -// +kubebuilder:object:generate=true -// +groupName=infrastructure.cluster.x-k8s.io package v1alpha7 import ( @@ -33,4 +30,6 @@ var ( // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder ) diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/identity_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/identity_types.go index 15cd5856..1ea5f2fb 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/identity_types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/identity_types.go @@ -16,8 +16,6 @@ limitations under the License. package v1alpha7 -const defaultIdentityRefKind = "Secret" - // OpenStackIdentityReference is a reference to an infrastructure // provider identity to be used to provision cluster resources. type OpenStackIdentityReference struct { diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_conversion.go new file mode 100644 index 00000000..cfdea6e2 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_conversion.go @@ -0,0 +1,496 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha7 + +import ( + "reflect" + + apiconversion "k8s.io/apimachinery/pkg/conversion" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + ctrlconversion "sigs.k8s.io/controller-runtime/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" +) + +var _ ctrlconversion.Convertible = &OpenStackCluster{} + +func (r *OpenStackCluster) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackCluster) + + return conversion.ConvertAndRestore( + r, dst, + Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster, Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster, + v1alpha7OpenStackClusterRestorer, v1beta1OpenStackClusterRestorer, + ) +} + +func (r *OpenStackCluster) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackCluster) + + return conversion.ConvertAndRestore( + src, r, + Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster, Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster, + v1beta1OpenStackClusterRestorer, v1alpha7OpenStackClusterRestorer, + ) +} + +var _ ctrlconversion.Convertible = &OpenStackClusterList{} + +func (r *OpenStackClusterList) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackClusterList) + + return Convert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList(r, dst, nil) +} + +func (r *OpenStackClusterList) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackClusterList) + + return Convert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList(src, r, nil) +} + +/* Restorers */ + +var v1alpha7OpenStackClusterRestorer = conversion.RestorerFor[*OpenStackCluster]{ + "bastion": conversion.HashedFieldRestorer( + func(c *OpenStackCluster) **Bastion { + return &c.Spec.Bastion + }, + restorev1alpha7Bastion, + ), + "spec": conversion.HashedFieldRestorer( + func(c *OpenStackCluster) *OpenStackClusterSpec { + return &c.Spec + }, + restorev1alpha7ClusterSpec, + // Filter out Bastion, which is restored separately, and + // ControlPlaneEndpoint, which is written by the cluster controller + conversion.HashedFilterField[*OpenStackCluster]( + func(s *OpenStackClusterSpec) *OpenStackClusterSpec { + if s.Bastion != nil || s.ControlPlaneEndpoint != (clusterv1.APIEndpoint{}) { + f := *s + f.Bastion = nil + f.ControlPlaneEndpoint = clusterv1.APIEndpoint{} + return &f + } + return s + }, + ), + ), + "status": conversion.HashedFieldRestorer( + func(c *OpenStackCluster) *OpenStackClusterStatus { + return &c.Status + }, + restorev1alpha7ClusterStatus, + ), +} + +var v1beta1OpenStackClusterRestorer = conversion.RestorerFor[*infrav1.OpenStackCluster]{ + "bastion": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackCluster) **infrav1.Bastion { + return &c.Spec.Bastion + }, + restorev1beta1Bastion, + ), + "spec": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackCluster) *infrav1.OpenStackClusterSpec { + return &c.Spec + }, + restorev1beta1ClusterSpec, + // Filter out Bastion, which is restored separately + conversion.HashedFilterField[*infrav1.OpenStackCluster, infrav1.OpenStackClusterSpec]( + func(s *infrav1.OpenStackClusterSpec) *infrav1.OpenStackClusterSpec { + if s.Bastion != nil { + f := *s + f.Bastion = nil + return &f + } + return s + }, + ), + ), + "status": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackCluster) *infrav1.OpenStackClusterStatus { + return &c.Status + }, + restorev1beta1ClusterStatus, + ), +} + +/* OpenStackClusterSpec */ + +func restorev1alpha7ClusterSpec(previous *OpenStackClusterSpec, dst *OpenStackClusterSpec) { + prevBastion := previous.Bastion + dstBastion := dst.Bastion + if prevBastion != nil && dstBastion != nil { + restorev1alpha7MachineSpec(&prevBastion.Instance, &dstBastion.Instance) + } + + // We only restore DNSNameservers when these were lossly converted when NodeCIDR is empty. + if len(previous.DNSNameservers) > 0 && dst.NodeCIDR == "" { + dst.DNSNameservers = previous.DNSNameservers + } + + // To avoid lossy conversion, we need to restore AllowAllInClusterTraffic + // even if ManagedSecurityGroups is set to false + if previous.AllowAllInClusterTraffic && !previous.ManagedSecurityGroups { + dst.AllowAllInClusterTraffic = true + } + + // Conversion to v1beta1 removes the Kind field + dst.IdentityRef = previous.IdentityRef + + if len(dst.ExternalRouterIPs) == len(previous.ExternalRouterIPs) { + for i := range dst.ExternalRouterIPs { + restorev1alpha7SubnetFilter(&previous.ExternalRouterIPs[i].Subnet, &dst.ExternalRouterIPs[i].Subnet) + } + } + + restorev1alpha7SubnetFilter(&previous.Subnet, &dst.Subnet) + + if dst.Router != nil && previous.Router != nil { + restorev1alpha7RouterFilter(previous.Router, dst.Router) + } + + restorev1alpha7NetworkFilter(&previous.Network, &dst.Network) +} + +func restorev1beta1ClusterSpec(previous *infrav1.OpenStackClusterSpec, dst *infrav1.OpenStackClusterSpec) { + if previous == nil || dst == nil { + return + } + + // Bastion is restored separately + + if dst.Network == nil { + dst.Network = previous.Network + } + + // ExternalNetwork by filter will be been lost in down-conversion + if previous.ExternalNetwork != nil { + if dst.ExternalNetwork == nil { + dst.ExternalNetwork = &infrav1.NetworkParam{} + } + dst.ExternalNetwork.Filter = previous.ExternalNetwork.Filter + } + + dst.DisableExternalNetwork = previous.DisableExternalNetwork + + restorev1beta1RouterParam(previous.Router, dst.Router) + restorev1beta1NetworkParam(previous.Network, dst.Network) + + if len(previous.Subnets) > 0 && len(dst.Subnets) > 0 { + restorev1beta1SubnetParam(&previous.Subnets[0], &dst.Subnets[0]) + } + if len(previous.Subnets) > 1 { + dst.Subnets = append(dst.Subnets, previous.Subnets[1:]...) + } + + if len(previous.ExternalRouterIPs) == len(dst.ExternalRouterIPs) { + for i := range dst.ExternalRouterIPs { + restorev1beta1SubnetParam(&previous.ExternalRouterIPs[i].Subnet, &dst.ExternalRouterIPs[i].Subnet) + } + } + + dst.ManagedSubnets = previous.ManagedSubnets + + if previous.ManagedSecurityGroups != nil && dst.ManagedSecurityGroups != nil { + dst.ManagedSecurityGroups.AllNodesSecurityGroupRules = previous.ManagedSecurityGroups.AllNodesSecurityGroupRules + } + + if dst.APIServerLoadBalancer != nil && previous.APIServerLoadBalancer != nil { + if dst.APIServerLoadBalancer.Enabled == nil || !*dst.APIServerLoadBalancer.Enabled { + dst.APIServerLoadBalancer.Enabled = previous.APIServerLoadBalancer.Enabled + } + optional.RestoreString(&previous.APIServerLoadBalancer.Provider, &dst.APIServerLoadBalancer.Provider) + + if previous.APIServerLoadBalancer.Network != nil { + dst.APIServerLoadBalancer.Network = previous.APIServerLoadBalancer.Network + } + + if previous.APIServerLoadBalancer.Subnets != nil { + dst.APIServerLoadBalancer.Subnets = previous.APIServerLoadBalancer.Subnets + } + } + if dst.APIServerLoadBalancer.IsZero() { + dst.APIServerLoadBalancer = previous.APIServerLoadBalancer + } + + if dst.ControlPlaneEndpoint == nil || *dst.ControlPlaneEndpoint == (clusterv1.APIEndpoint{}) { + dst.ControlPlaneEndpoint = previous.ControlPlaneEndpoint + } + + optional.RestoreString(&previous.APIServerFloatingIP, &dst.APIServerFloatingIP) + optional.RestoreString(&previous.APIServerFixedIP, &dst.APIServerFixedIP) + optional.RestoreInt(&previous.APIServerPort, &dst.APIServerPort) + optional.RestoreBool(&previous.DisableAPIServerFloatingIP, &dst.DisableAPIServerFloatingIP) + optional.RestoreBool(&previous.ControlPlaneOmitAvailabilityZone, &dst.ControlPlaneOmitAvailabilityZone) + optional.RestoreBool(&previous.DisablePortSecurity, &dst.DisablePortSecurity) + + restorev1beta1APIServerLoadBalancer(previous.APIServerLoadBalancer, dst.APIServerLoadBalancer) +} + +func Convert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in *OpenStackClusterSpec, out *infrav1.OpenStackClusterSpec, s apiconversion.Scope) error { + err := autoConvert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in, out, s) + if err != nil { + return err + } + + if in.Network != (NetworkFilter{}) { + out.Network = &infrav1.NetworkParam{} + if err := Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkParam(&in.Network, out.Network, s); err != nil { + return err + } + } + + if in.ExternalNetworkID != "" { + out.ExternalNetwork = &infrav1.NetworkParam{ + ID: &in.ExternalNetworkID, + } + } + + emptySubnet := SubnetFilter{} + if in.Subnet != emptySubnet { + subnet := infrav1.SubnetParam{} + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &subnet, s); err != nil { + return err + } + out.Subnets = []infrav1.SubnetParam{subnet} + } + + // DNSNameservers without NodeCIDR doesn't make sense, so we drop that. + if len(in.NodeCIDR) > 0 { + out.ManagedSubnets = []infrav1.SubnetSpec{ + { + CIDR: in.NodeCIDR, + DNSNameservers: in.DNSNameservers, + }, + } + } + + if in.ManagedSecurityGroups { + out.ManagedSecurityGroups = &infrav1.ManagedSecurityGroups{} + if !in.AllowAllInClusterTraffic { + out.ManagedSecurityGroups.AllNodesSecurityGroupRules = infrav1.LegacyCalicoSecurityGroupRules() + } else { + out.ManagedSecurityGroups.AllowAllInClusterTraffic = true + } + } + + if in.ControlPlaneEndpoint != (clusterv1.APIEndpoint{}) { + out.ControlPlaneEndpoint = &in.ControlPlaneEndpoint + } + + out.IdentityRef.CloudName = in.CloudName + if in.IdentityRef != nil { + out.IdentityRef.Name = in.IdentityRef.Name + } + + apiServerLoadBalancer := &infrav1.APIServerLoadBalancer{} + if err := Convert_v1alpha7_APIServerLoadBalancer_To_v1beta1_APIServerLoadBalancer(&in.APIServerLoadBalancer, apiServerLoadBalancer, s); err != nil { + return err + } + if !apiServerLoadBalancer.IsZero() { + out.APIServerLoadBalancer = apiServerLoadBalancer + } + + return nil +} + +func Convert_v1beta1_LoadBalancer_To_v1alpha7_LoadBalancer(in *infrav1.LoadBalancer, out *LoadBalancer, s apiconversion.Scope) error { + return autoConvert_v1beta1_LoadBalancer_To_v1alpha7_LoadBalancer(in, out, s) +} + +func Convert_v1beta1_APIServerLoadBalancer_To_v1alpha7_APIServerLoadBalancer(in *infrav1.APIServerLoadBalancer, out *APIServerLoadBalancer, s apiconversion.Scope) error { + return autoConvert_v1beta1_APIServerLoadBalancer_To_v1alpha7_APIServerLoadBalancer(in, out, s) +} + +func Convert_v1alpha7_APIServerLoadBalancer_To_v1beta1_APIServerLoadBalancer(in *APIServerLoadBalancer, out *infrav1.APIServerLoadBalancer, s apiconversion.Scope) error { + return autoConvert_v1alpha7_APIServerLoadBalancer_To_v1beta1_APIServerLoadBalancer(in, out, s) +} + +func Convert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(in *infrav1.OpenStackClusterSpec, out *OpenStackClusterSpec, s apiconversion.Scope) error { + err := autoConvert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(in, out, s) + if err != nil { + return err + } + + if in.Network != nil { + if err := Convert_v1beta1_NetworkParam_To_v1alpha7_NetworkFilter(in.Network, &out.Network, s); err != nil { + return err + } + } + + if in.ExternalNetwork != nil && in.ExternalNetwork.ID != nil { + out.ExternalNetworkID = *in.ExternalNetwork.ID + } + + if len(in.Subnets) >= 1 { + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(&in.Subnets[0], &out.Subnet, s); err != nil { + return err + } + } + + if len(in.ManagedSubnets) > 0 { + out.NodeCIDR = in.ManagedSubnets[0].CIDR + out.DNSNameservers = in.ManagedSubnets[0].DNSNameservers + } + + if in.ManagedSecurityGroups != nil { + out.ManagedSecurityGroups = true + out.AllowAllInClusterTraffic = in.ManagedSecurityGroups.AllowAllInClusterTraffic + } + + if in.ControlPlaneEndpoint != nil { + out.ControlPlaneEndpoint = *in.ControlPlaneEndpoint + } + + out.CloudName = in.IdentityRef.CloudName + out.IdentityRef = &OpenStackIdentityReference{} + if err := Convert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityReference(&in.IdentityRef, out.IdentityRef, s); err != nil { + return err + } + + if in.APIServerLoadBalancer != nil { + if err := Convert_v1beta1_APIServerLoadBalancer_To_v1alpha7_APIServerLoadBalancer(in.APIServerLoadBalancer, &out.APIServerLoadBalancer, s); err != nil { + return err + } + } + + return nil +} + +/* OpenStackClusterStatus */ + +func restorev1alpha7ClusterStatus(previous *OpenStackClusterStatus, dst *OpenStackClusterStatus) { + restorev1alpha7SecurityGroup(previous.ControlPlaneSecurityGroup, dst.ControlPlaneSecurityGroup) + restorev1alpha7SecurityGroup(previous.WorkerSecurityGroup, dst.WorkerSecurityGroup) + restorev1alpha7SecurityGroup(previous.BastionSecurityGroup, dst.BastionSecurityGroup) +} + +func restorev1beta1ClusterStatus(previous *infrav1.OpenStackClusterStatus, dst *infrav1.OpenStackClusterStatus) { + if previous == nil || dst == nil { + return + } + + restorev1beta1BastionStatus(previous.Bastion, dst.Bastion) + + if previous.APIServerLoadBalancer != nil { + dst.APIServerLoadBalancer = previous.APIServerLoadBalancer + } +} + +func Convert_v1beta1_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(in *infrav1.OpenStackClusterStatus, out *OpenStackClusterStatus, s apiconversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(in, out, s) +} + +/* Bastion */ + +func restorev1alpha7Bastion(previous **Bastion, dst **Bastion) { + if previous == nil || dst == nil || *previous == nil || *dst == nil { + return + } + prevMachineSpec := &(*previous).Instance + dstMachineSpec := &(*dst).Instance + restorev1alpha7MachineSpec(prevMachineSpec, dstMachineSpec) + dstMachineSpec.InstanceID = prevMachineSpec.InstanceID +} + +func restorev1beta1Bastion(previous **infrav1.Bastion, dst **infrav1.Bastion) { + if previous == nil || dst == nil || *previous == nil || *dst == nil { + return + } + + restorev1beta1MachineSpec((*previous).Spec, (*dst).Spec) + optional.RestoreString(&(*previous).FloatingIP, &(*dst).FloatingIP) + optional.RestoreString(&(*previous).AvailabilityZone, &(*dst).AvailabilityZone) + + if (*dst).Enabled != nil && !*(*dst).Enabled { + (*dst).Enabled = (*previous).Enabled + } +} + +func Convert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *infrav1.Bastion, s apiconversion.Scope) error { + err := autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in, out, s) + if err != nil { + return err + } + + if !reflect.ValueOf(in.Instance).IsZero() { + out.Spec = &infrav1.OpenStackMachineSpec{} + + err = Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(&in.Instance, out.Spec, s) + if err != nil { + return err + } + + if in.Instance.ServerGroupID != "" { + out.Spec.ServerGroup = &infrav1.ServerGroupParam{ID: &in.Instance.ServerGroupID} + } else { + out.Spec.ServerGroup = nil + } + + err = optional.Convert_string_To_optional_String(&in.Instance.FloatingIP, &out.FloatingIP, s) + if err != nil { + return err + } + } + + // nil the Spec if it's basically an empty object. + if out.Spec != nil && reflect.ValueOf(*out.Spec).IsZero() { + out.Spec = nil + } + return nil +} + +func Convert_v1beta1_Bastion_To_v1alpha7_Bastion(in *infrav1.Bastion, out *Bastion, s apiconversion.Scope) error { + err := autoConvert_v1beta1_Bastion_To_v1alpha7_Bastion(in, out, s) + if err != nil { + return err + } + + if in.Spec != nil { + err = Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in.Spec, &out.Instance, s) + if err != nil { + return err + } + + if in.Spec.ServerGroup != nil && in.Spec.ServerGroup.ID != nil { + out.Instance.ServerGroupID = *in.Spec.ServerGroup.ID + } + } + + return optional.Convert_optional_String_To_string(&in.FloatingIP, &out.Instance.FloatingIP, s) +} + +/* Bastion status */ + +func restorev1beta1BastionStatus(previous *infrav1.BastionStatus, dst *infrav1.BastionStatus) { + if previous == nil || dst == nil { + return + } + + // Resolved and resources have no equivalents + dst.Resolved = previous.Resolved + dst.Resources = previous.Resources +} + +func Convert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(in *infrav1.BastionStatus, out *BastionStatus, s apiconversion.Scope) error { + // ReferencedResources have no equivalent in v1alpha7 + return autoConvert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(in, out, s) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_types.go index b4826685..ef0ea517 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_types.go @@ -229,9 +229,10 @@ type OpenStackClusterStatus struct { FailureMessage *string `json:"failureMessage,omitempty"` } +// +genclient +// +genclient:Namespaced // +kubebuilder:object:root=true // +kubebuilder:resource:path=openstackclusters,scope=Namespaced,categories=cluster-api,shortName=osc -// +kubebuilder:storageversion // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this OpenStackCluster belongs" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Cluster infrastructure is ready for OpenStack instances" diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_webhook.go deleted file mode 100644 index 706d10a8..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackcluster_webhook.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "fmt" - "reflect" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/validation/field" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/builder" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// log is for logging in this package. -var _ = logf.Log.WithName("openstackcluster-resource") - -func (r *OpenStackCluster) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(r). - Complete() -} - -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters,versions=v1alpha7,name=validation.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 -// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters,versions=v1alpha7,name=default.openstackcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 - -var ( - _ webhook.Defaulter = &OpenStackCluster{} - _ webhook.Validator = &OpenStackCluster{} -) - -// Default satisfies the defaulting webhook interface. -func (r *OpenStackCluster) Default() { - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind == "" { - r.Spec.IdentityRef.Kind = defaultIdentityRefKind - } -} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackCluster) ValidateCreate() (admission.Warnings, error) { - var allErrs field.ErrorList - - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind != defaultIdentityRefKind { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "identityRef", "kind"), "must be a Secret")) - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackCluster) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings, error) { - var allErrs field.ErrorList - old, ok := oldRaw.(*OpenStackCluster) - if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an OpenStackCluster but got a %T", oldRaw)) - } - - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind != defaultIdentityRefKind { - allErrs = append(allErrs, - field.Invalid(field.NewPath("spec", "identityRef", "kind"), - r.Spec.IdentityRef, "must be a Secret"), - ) - } - - // Allow changes to Spec.IdentityRef.Name. - if old.Spec.IdentityRef != nil && r.Spec.IdentityRef != nil { - old.Spec.IdentityRef.Name = "" - r.Spec.IdentityRef.Name = "" - } - - // Allow changes to Spec.IdentityRef if it was unset. - if old.Spec.IdentityRef == nil && r.Spec.IdentityRef != nil { - old.Spec.IdentityRef = &OpenStackIdentityReference{} - r.Spec.IdentityRef = &OpenStackIdentityReference{} - } - - if old.Spec.IdentityRef != nil && r.Spec.IdentityRef == nil { - allErrs = append(allErrs, - field.Invalid(field.NewPath("spec", "identityRef"), - r.Spec.IdentityRef, "field cannot be set to nil"), - ) - } - - // Allow change only for the first time. - if old.Spec.ControlPlaneEndpoint.Host == "" { - old.Spec.ControlPlaneEndpoint = clusterv1.APIEndpoint{} - r.Spec.ControlPlaneEndpoint = clusterv1.APIEndpoint{} - } - - // Allow change only for the first time. - if old.Spec.DisableAPIServerFloatingIP && old.Spec.APIServerFixedIP == "" { - r.Spec.APIServerFixedIP = "" - } - - // If API Server floating IP is disabled, allow the change of the API Server port only for the first time. - if old.Spec.DisableAPIServerFloatingIP && old.Spec.APIServerPort == 0 && r.Spec.APIServerPort > 0 { - r.Spec.APIServerPort = 0 - } - - // Allow changes to the bastion spec. - old.Spec.Bastion = &Bastion{} - r.Spec.Bastion = &Bastion{} - - // Allow changes on AllowedCIDRs - if r.Spec.APIServerLoadBalancer.Enabled { - old.Spec.APIServerLoadBalancer.AllowedCIDRs = []string{} - r.Spec.APIServerLoadBalancer.AllowedCIDRs = []string{} - } - - // Allow changes to the availability zones. - old.Spec.ControlPlaneAvailabilityZones = []string{} - r.Spec.ControlPlaneAvailabilityZones = []string{} - - // Allow change to the allowAllInClusterTraffic. - old.Spec.AllowAllInClusterTraffic = false - r.Spec.AllowAllInClusterTraffic = false - - // Allow change on the spec.APIServerFloatingIP only if it matches the current api server loadbalancer IP. - if old.Status.APIServerLoadBalancer != nil && r.Spec.APIServerFloatingIP == old.Status.APIServerLoadBalancer.IP { - r.Spec.APIServerFloatingIP = "" - old.Spec.APIServerFloatingIP = "" - } - - if !reflect.DeepEqual(old.Spec, r.Spec) { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "cannot be modified")) - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackCluster) ValidateDelete() (admission.Warnings, error) { - return nil, nil -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_conversion.go new file mode 100644 index 00000000..1cf6e699 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_conversion.go @@ -0,0 +1,88 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha7 + +import ( + ctrlconversion "sigs.k8s.io/controller-runtime/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion" +) + +var _ ctrlconversion.Convertible = &OpenStackClusterTemplate{} + +func (r *OpenStackClusterTemplate) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackClusterTemplate) + + return conversion.ConvertAndRestore( + r, dst, + Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate, Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate, + v1alpha7OpenStackClusterTemplateRestorer, v1beta1OpenStackClusterTemplateRestorer, + ) +} + +func (r *OpenStackClusterTemplate) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackClusterTemplate) + + return conversion.ConvertAndRestore( + src, r, + Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate, Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate, + v1beta1OpenStackClusterTemplateRestorer, v1alpha7OpenStackClusterTemplateRestorer, + ) +} + +var _ ctrlconversion.Convertible = &OpenStackClusterTemplateList{} + +func (r *OpenStackClusterTemplateList) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackClusterTemplateList) + return Convert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList(r, dst, nil) +} + +func (r *OpenStackClusterTemplateList) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackClusterTemplateList) + return Convert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList(src, r, nil) +} + +/* Restorers */ + +var v1alpha7OpenStackClusterTemplateRestorer = conversion.RestorerFor[*OpenStackClusterTemplate]{ + "spec": conversion.HashedFieldRestorer( + func(c *OpenStackClusterTemplate) *OpenStackClusterTemplateSpec { + return &c.Spec + }, + restorev1alpha7ClusterTemplateSpec, + ), +} + +var v1beta1OpenStackClusterTemplateRestorer = conversion.RestorerFor[*infrav1.OpenStackClusterTemplate]{ + "spec": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackClusterTemplate) *infrav1.OpenStackClusterTemplateSpec { + return &c.Spec + }, + restorev1beta1ClusterTemplateSpec, + ), +} + +func restorev1alpha7ClusterTemplateSpec(previous *OpenStackClusterTemplateSpec, dst *OpenStackClusterTemplateSpec) { + restorev1alpha7ClusterSpec(&previous.Template.Spec, &dst.Template.Spec) + restorev1alpha7Bastion(&previous.Template.Spec.Bastion, &dst.Template.Spec.Bastion) +} + +func restorev1beta1ClusterTemplateSpec(previous *infrav1.OpenStackClusterTemplateSpec, dst *infrav1.OpenStackClusterTemplateSpec) { + restorev1beta1Bastion(&previous.Template.Spec.Bastion, &dst.Template.Spec.Bastion) + restorev1beta1ClusterSpec(&previous.Template.Spec, &dst.Template.Spec) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_types.go index c255284a..1c9a41b2 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_types.go @@ -30,9 +30,10 @@ type OpenStackClusterTemplateSpec struct { Template OpenStackClusterTemplateResource `json:"template"` } -//+kubebuilder:object:root=true -// +kubebuilder:storageversion -//+kubebuilder:resource:path=openstackclustertemplates,scope=Namespaced,categories=cluster-api,shortName=osct +// +genclient +// +genclient:Namespaced +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=openstackclustertemplates,scope=Namespaced,categories=cluster-api,shortName=osct // OpenStackClusterTemplate is the Schema for the openstackclustertemplates API. type OpenStackClusterTemplate struct { diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_webhook.go deleted file mode 100644 index 337928a3..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclustertemplate_webhook.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "fmt" - "reflect" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/validation/field" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -const openStackClusterTemplateImmutableMsg = "OpenStackClusterTemplate spec.template.spec field is immutable. Please create new resource instead." - -func (r *OpenStackClusterTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr). - For(r). - Complete() -} - -// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackclustertemplate,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclustertemplates,versions=v1alpha7,name=default.openstackclustertemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackclustertemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackclustertemplates,versions=v1alpha7,name=validation.openstackclustertemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 - -var ( - _ webhook.Defaulter = &OpenStackClusterTemplate{} - _ webhook.Validator = &OpenStackClusterTemplate{} -) - -// Default implements webhook.Defaulter so a webhook will be registered for the type. -func (r *OpenStackClusterTemplate) Default() { - if r.Spec.Template.Spec.IdentityRef != nil && r.Spec.Template.Spec.IdentityRef.Kind == "" { - r.Spec.Template.Spec.IdentityRef.Kind = defaultIdentityRefKind - } -} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackClusterTemplate) ValidateCreate() (admission.Warnings, error) { - var allErrs field.ErrorList - - if r.Spec.Template.Spec.IdentityRef != nil && r.Spec.Template.Spec.IdentityRef.Kind != defaultIdentityRefKind { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "identityRef", "kind"), "must be a Secret")) - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackClusterTemplate) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings, error) { - var allErrs field.ErrorList - old, ok := oldRaw.(*OpenStackClusterTemplate) - if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an OpenStackClusterTemplate but got a %T", oldRaw)) - } - - if !reflect.DeepEqual(r.Spec.Template.Spec, old.Spec.Template.Spec) { - allErrs = append(allErrs, - field.Invalid(field.NewPath("OpenStackClusterTemplate", "spec", "template", "spec"), r, openStackClusterTemplateImmutableMsg), - ) - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackClusterTemplate) ValidateDelete() (admission.Warnings, error) { - return nil, nil -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_conversion.go new file mode 100644 index 00000000..5183b3fa --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_conversion.go @@ -0,0 +1,297 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha7 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + ctrlconversion "sigs.k8s.io/controller-runtime/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion" +) + +var _ ctrlconversion.Convertible = &OpenStackMachine{} + +func (r *OpenStackMachine) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackMachine) + + return conversion.ConvertAndRestore( + r, dst, + Convert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine, Convert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine, + v1alpha7OpenStackMachineRestorer, v1beta1OpenStackMachineRestorer, + ) +} + +func (r *OpenStackMachine) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackMachine) + + return conversion.ConvertAndRestore( + src, r, + Convert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine, Convert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine, + v1beta1OpenStackMachineRestorer, v1alpha7OpenStackMachineRestorer, + ) +} + +var _ ctrlconversion.Convertible = &OpenStackMachineList{} + +func (r *OpenStackMachineList) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackMachineList) + return Convert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList(r, dst, nil) +} + +func (r *OpenStackMachineList) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackMachineList) + return Convert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList(src, r, nil) +} + +/* Restorers */ + +var v1alpha7OpenStackMachineRestorer = conversion.RestorerFor[*OpenStackMachine]{ + "spec": conversion.HashedFieldRestorer( + func(c *OpenStackMachine) *OpenStackMachineSpec { + return &c.Spec + }, + restorev1alpha7MachineSpec, + conversion.HashedFilterField[*OpenStackMachine, OpenStackMachineSpec](func(s *OpenStackMachineSpec) *OpenStackMachineSpec { + // Despite being spec fields, ProviderID and InstanceID + // are both set by the machine controller. If these are + // the only changes to the spec, we still want to + // restore the rest of the spec to its original state. + if s.ProviderID != nil || s.InstanceID != nil { + f := *s + f.ProviderID = nil + f.InstanceID = nil + return &f + } + return s + }), + ), +} + +var v1beta1OpenStackMachineRestorer = conversion.RestorerFor[*infrav1.OpenStackMachine]{ + "spec": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackMachine) *infrav1.OpenStackMachineSpec { + return &c.Spec + }, + restorev1beta1MachineSpec, + ), + "depresources": conversion.UnconditionalFieldRestorer( + func(c *infrav1.OpenStackMachine) **infrav1.MachineResources { + return &c.Status.Resources + }, + ), + // No equivalent in v1alpha7 + "refresources": conversion.UnconditionalFieldRestorer( + func(c *infrav1.OpenStackMachine) **infrav1.ResolvedMachineSpec { + return &c.Status.Resolved + }, + ), +} + +/* OpenStackMachine */ + +func Convert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine(in *OpenStackMachine, out *infrav1.OpenStackMachine, s apiconversion.Scope) error { + err := autoConvert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine(in, out, s) + if err != nil { + return err + } + + out.Status.InstanceID = in.Spec.InstanceID + return nil +} + +func Convert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine(in *infrav1.OpenStackMachine, out *OpenStackMachine, s apiconversion.Scope) error { + err := autoConvert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine(in, out, s) + if err != nil { + return err + } + + out.Spec.InstanceID = in.Status.InstanceID + return nil +} + +/* OpenStackMachineSpec */ + +func restorev1alpha7MachineSpec(previous *OpenStackMachineSpec, dst *OpenStackMachineSpec) { + dst.FloatingIP = previous.FloatingIP + + // Conversion to v1beta1 truncates keys and values to 255 characters + for k, v := range previous.ServerMetadata { + kd := k + if len(k) > 255 { + kd = k[:255] + } + + vd := v + if len(v) > 255 { + vd = v[:255] + } + + if kd != k || vd != v { + if dst.ServerMetadata == nil { + dst.ServerMetadata = make(map[string]string) + } + delete(dst.ServerMetadata, kd) + dst.ServerMetadata[k] = v + } + } + + // Conversion to v1beta1 removes the Kind field + dst.IdentityRef = previous.IdentityRef + + if len(dst.Ports) == len(previous.Ports) { + for i := range dst.Ports { + restorev1alpha7Port(&previous.Ports[i], &dst.Ports[i]) + } + } + + if len(dst.SecurityGroups) == len(previous.SecurityGroups) { + for i := range dst.SecurityGroups { + restorev1alpha7SecurityGroupFilter(&previous.SecurityGroups[i], &dst.SecurityGroups[i]) + } + } + + // Conversion to v1beta1 removes Image when ImageUUID is set + if dst.Image == "" && previous.Image != "" { + dst.Image = previous.Image + } +} + +func restorev1beta1MachineSpec(previous *infrav1.OpenStackMachineSpec, dst *infrav1.OpenStackMachineSpec) { + if previous == nil || dst == nil { + return + } + + dst.ServerGroup = previous.ServerGroup + dst.Image = previous.Image + + if len(dst.SecurityGroups) == len(previous.SecurityGroups) { + for i := range dst.SecurityGroups { + restorev1beta1SecurityGroupParam(&previous.SecurityGroups[i], &dst.SecurityGroups[i]) + } + } + + if len(dst.Ports) == len(previous.Ports) { + for i := range dst.Ports { + restorev1beta1Port(&previous.Ports[i], &dst.Ports[i]) + } + } + dst.FloatingIPPoolRef = previous.FloatingIPPoolRef + + if dst.RootVolume != nil && previous.RootVolume != nil { + restorev1beta1BlockDeviceVolume( + &previous.RootVolume.BlockDeviceVolume, + &dst.RootVolume.BlockDeviceVolume, + ) + } + + if len(dst.AdditionalBlockDevices) == len(previous.AdditionalBlockDevices) { + for i := range dst.AdditionalBlockDevices { + restorev1beta1BlockDeviceVolume( + previous.AdditionalBlockDevices[i].Storage.Volume, + dst.AdditionalBlockDevices[i].Storage.Volume, + ) + } + } +} + +func Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in *OpenStackMachineSpec, out *infrav1.OpenStackMachineSpec, s apiconversion.Scope) error { + err := autoConvert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in, out, s) + if err != nil { + return err + } + + if in.ServerGroupID != "" { + out.ServerGroup = &infrav1.ServerGroupParam{ID: &in.ServerGroupID} + } else { + out.ServerGroup = nil + } + + imageParam := infrav1.ImageParam{} + if in.ImageUUID != "" { + imageParam.ID = &in.ImageUUID + } else if in.Image != "" { // Only add name when ID is not set, in v1beta1 it's not possible to set both. + imageParam.Filter = &infrav1.ImageFilter{Name: &in.Image} + } + out.Image = imageParam + + if len(in.ServerMetadata) > 0 { + serverMetadata := make([]infrav1.ServerMetadata, 0, len(in.ServerMetadata)) + for k, v := range in.ServerMetadata { + // Truncate key and value to 255 characters if required, as this + // was not validated prior to v1beta1 + if len(k) > 255 { + k = k[:255] + } + if len(v) > 255 { + v = v[:255] + } + + serverMetadata = append(serverMetadata, infrav1.ServerMetadata{Key: k, Value: v}) + } + out.ServerMetadata = serverMetadata + } + + if in.CloudName != "" { + if out.IdentityRef == nil { + out.IdentityRef = &infrav1.OpenStackIdentityReference{} + } + out.IdentityRef.CloudName = in.CloudName + } + + return nil +} + +func Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *infrav1.OpenStackMachineSpec, out *OpenStackMachineSpec, s apiconversion.Scope) error { + err := autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in, out, s) + if err != nil { + return err + } + + if in.ServerGroup != nil && in.ServerGroup.ID != nil { + out.ServerGroupID = *in.ServerGroup.ID + } + + if in.Image.ID != nil { + out.ImageUUID = *in.Image.ID + } else if in.Image.Filter != nil && in.Image.Filter.Name != nil { + out.Image = *in.Image.Filter.Name + } + + if len(in.ServerMetadata) > 0 { + serverMetadata := make(map[string]string, len(in.ServerMetadata)) + for i := range in.ServerMetadata { + key := in.ServerMetadata[i].Key + value := in.ServerMetadata[i].Value + serverMetadata[key] = value + } + out.ServerMetadata = serverMetadata + } + + if in.IdentityRef != nil { + out.CloudName = in.IdentityRef.CloudName + } + + return nil +} + +/* OpenStackMachineStatus */ + +func Convert_v1beta1_OpenStackMachineStatus_To_v1alpha7_OpenStackMachineStatus(in *infrav1.OpenStackMachineStatus, out *OpenStackMachineStatus, s apiconversion.Scope) error { + // ReferencedResources have no equivalent in v1alpha7 + return autoConvert_v1beta1_OpenStackMachineStatus_To_v1alpha7_OpenStackMachineStatus(in, out, s) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_types.go index 0be14961..043359db 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_types.go @@ -19,7 +19,7 @@ package v1alpha7 import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/errors" ) @@ -136,8 +136,9 @@ type OpenStackMachineStatus struct { Conditions clusterv1.Conditions `json:"conditions,omitempty"` } +// +genclient +// +genclient:Namespaced // +kubebuilder:object:root=true -// +kubebuilder:storageversion // +kubebuilder:resource:path=openstackmachines,scope=Namespaced,categories=cluster-api,shortName=osm // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this OpenStackMachine belongs" @@ -178,7 +179,7 @@ func (r *OpenStackMachine) SetConditions(conditions clusterv1.Conditions) { // SetFailure sets the OpenStackMachine status failure reason and failure message. func (r *OpenStackMachine) SetFailure(failureReason errors.MachineStatusError, failureMessage error) { r.Status.FailureReason = &failureReason - r.Status.FailureMessage = pointer.String(failureMessage.Error()) + r.Status.FailureMessage = ptr.To(failureMessage.Error()) } func init() { diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_webhook.go deleted file mode 100644 index 6470589a..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachine_webhook.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "fmt" - "reflect" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/validation/field" - "sigs.k8s.io/controller-runtime/pkg/builder" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// log is for logging in this package. -var _ = logf.Log.WithName("openstackmachine-resource") - -func (r *OpenStackMachine) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(r). - Complete() -} - -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackmachine,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackmachines,versions=v1alpha7,name=validation.openstackmachine.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 -// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackmachine,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackmachines,versions=v1alpha7,name=default.openstackmachine.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 - -var ( - _ webhook.Defaulter = &OpenStackMachine{} - _ webhook.Validator = &OpenStackMachine{} -) - -// Default satisfies the defaulting webhook interface. -func (r *OpenStackMachine) Default() { - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind == "" { - r.Spec.IdentityRef.Kind = defaultIdentityRefKind - } -} - -// ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackMachine) ValidateCreate() (admission.Warnings, error) { - var allErrs field.ErrorList - - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind != defaultIdentityRefKind { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "identityRef", "kind"), "must be a Secret")) - } - - if r.Spec.RootVolume != nil && r.Spec.AdditionalBlockDevices != nil { - for _, device := range r.Spec.AdditionalBlockDevices { - if device.Name == "root" { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "additionalBlockDevices"), "cannot contain a device named \"root\" when rootVolume is set")) - } - } - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackMachine) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - newOpenStackMachine, err := runtime.DefaultUnstructuredConverter.ToUnstructured(r) - if err != nil { - return nil, apierrors.NewInvalid(GroupVersion.WithKind("OpenStackMachine").GroupKind(), r.Name, field.ErrorList{ - field.InternalError(nil, fmt.Errorf("failed to convert new OpenStackMachine to unstructured object: %w", err)), - }) - } - oldOpenStackMachine, err := runtime.DefaultUnstructuredConverter.ToUnstructured(old) - if err != nil { - return nil, apierrors.NewInvalid(GroupVersion.WithKind("OpenStackMachine").GroupKind(), r.Name, field.ErrorList{ - field.InternalError(nil, fmt.Errorf("failed to convert old OpenStackMachine to unstructured object: %w", err)), - }) - } - - var allErrs field.ErrorList - - if r.Spec.IdentityRef != nil && r.Spec.IdentityRef.Kind != defaultIdentityRefKind { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "identityRef", "kind"), "must be a Secret")) - } - - newOpenStackMachineSpec := newOpenStackMachine["spec"].(map[string]interface{}) - oldOpenStackMachineSpec := oldOpenStackMachine["spec"].(map[string]interface{}) - - // allow changes to providerID once - if oldOpenStackMachineSpec["providerID"] == nil { - delete(oldOpenStackMachineSpec, "providerID") - delete(newOpenStackMachineSpec, "providerID") - } - - // allow changes to instanceID once - if oldOpenStackMachineSpec["instanceID"] == nil { - delete(oldOpenStackMachineSpec, "instanceID") - delete(newOpenStackMachineSpec, "instanceID") - } - - if !reflect.DeepEqual(oldOpenStackMachineSpec, newOpenStackMachineSpec) { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec"), "cannot be modified")) - } - - return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs) -} - -// ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (r *OpenStackMachine) ValidateDelete() (admission.Warnings, error) { - return nil, nil -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_conversion.go new file mode 100644 index 00000000..62ee4739 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_conversion.go @@ -0,0 +1,89 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha7 + +import ( + ctrlconversion "sigs.k8s.io/controller-runtime/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion" +) + +var _ ctrlconversion.Convertible = &OpenStackMachineTemplate{} + +func (r *OpenStackMachineTemplate) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackMachineTemplate) + + return conversion.ConvertAndRestore( + r, dst, + Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate, Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate, + v1alpha7OpenStackMachineTemplateRestorer, v1beta1OpenStackMachineTemplateRestorer, + ) +} + +func (r *OpenStackMachineTemplate) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackMachineTemplate) + + return conversion.ConvertAndRestore( + src, r, + Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate, Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate, + v1beta1OpenStackMachineTemplateRestorer, v1alpha7OpenStackMachineTemplateRestorer, + ) +} + +var _ ctrlconversion.Convertible = &OpenStackMachineTemplateList{} + +func (r *OpenStackMachineTemplateList) ConvertTo(dstRaw ctrlconversion.Hub) error { + dst := dstRaw.(*infrav1.OpenStackMachineTemplateList) + return Convert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList(r, dst, nil) +} + +func (r *OpenStackMachineTemplateList) ConvertFrom(srcRaw ctrlconversion.Hub) error { + src := srcRaw.(*infrav1.OpenStackMachineTemplateList) + return Convert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList(src, r, nil) +} + +/* Restorers */ + +var v1alpha7OpenStackMachineTemplateRestorer = conversion.RestorerFor[*OpenStackMachineTemplate]{ + "spec": conversion.HashedFieldRestorer( + func(c *OpenStackMachineTemplate) *OpenStackMachineTemplateSpec { + return &c.Spec + }, + restorev1alpha7MachineTemplateSpec, + ), +} + +var v1beta1OpenStackMachineTemplateRestorer = conversion.RestorerFor[*infrav1.OpenStackMachineTemplate]{ + "spec": conversion.HashedFieldRestorer( + func(c *infrav1.OpenStackMachineTemplate) *infrav1.OpenStackMachineSpec { + return &c.Spec.Template.Spec + }, + restorev1beta1MachineSpec, + ), +} + +func restorev1alpha7MachineTemplateSpec(previous *OpenStackMachineTemplateSpec, dst *OpenStackMachineTemplateSpec) { + if previous == nil || dst == nil { + return + } + + prevMachineSpec := &previous.Template.Spec + dstMachineSpec := &dst.Template.Spec + restorev1alpha7MachineSpec(prevMachineSpec, dstMachineSpec) + dstMachineSpec.InstanceID = prevMachineSpec.InstanceID +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_types.go index 5202234b..dc0eb97c 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_types.go @@ -25,8 +25,9 @@ type OpenStackMachineTemplateSpec struct { Template OpenStackMachineTemplateResource `json:"template"` } +// +genclient +// +genclient:Namespaced // +kubebuilder:object:root=true -// +kubebuilder:storageversion // +kubebuilder:resource:path=openstackmachinetemplates,scope=Namespaced,categories=cluster-api,shortName=osmt // OpenStackMachineTemplate is the Schema for the openstackmachinetemplates API. diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_webhook.go deleted file mode 100644 index b74d056b..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplate_webhook.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "context" - "fmt" - "reflect" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/validation/field" - "sigs.k8s.io/cluster-api/util/topology" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/webhook" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -// OpenStackMachineTemplateImmutableMsg ... -const OpenStackMachineTemplateImmutableMsg = "OpenStackMachineTemplate spec.template.spec field is immutable. Please create a new resource instead. Ref doc: https://cluster-api.sigs.k8s.io/tasks/change-machine-template.html" - -// +kubebuilder:object:generate=false -type OpenStackMachineTemplateWebhook struct{} - -func (r *OpenStackMachineTemplateWebhook) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(&OpenStackMachineTemplate{}). - WithValidator(r). - Complete() -} - -// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha7-openstackmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=openstackmachinetemplates,versions=v1alpha7,name=validation.openstackmachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1 - -var _ webhook.CustomValidator = &OpenStackMachineTemplateWebhook{} - -// ValidateCreate implements webhook.CustomValidator so a webhook will be registered for the type. -func (r *OpenStackMachineTemplateWebhook) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { - openStackMachineTemplate, ok := obj.(*OpenStackMachineTemplate) - if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an OpenStackMachineTemplate but got a %T", obj)) - } - - var allErrs field.ErrorList - - if openStackMachineTemplate.Spec.Template.Spec.ProviderID != nil { - allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "providerID"), "cannot be set in templates")) - } - - return aggregateObjErrors(openStackMachineTemplate.GroupVersionKind().GroupKind(), openStackMachineTemplate.Name, allErrs) -} - -// ValidateUpdate implements webhook.CustomValidator so a webhook will be registered for the type. -func (r *OpenStackMachineTemplateWebhook) ValidateUpdate(ctx context.Context, oldRaw runtime.Object, newRaw runtime.Object) (admission.Warnings, error) { - var allErrs field.ErrorList - old, ok := oldRaw.(*OpenStackMachineTemplate) - if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an OpenStackMachineTemplate but got a %T", oldRaw)) - } - - newObj, ok := newRaw.(*OpenStackMachineTemplate) - if !ok { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an OpenStackMachineTemplate but got a %T", oldRaw)) - } - - req, err := admission.RequestFromContext(ctx) - if err != nil { - return nil, apierrors.NewBadRequest(fmt.Sprintf("expected a admission.Request inside context: %v", err)) - } - - if !topology.ShouldSkipImmutabilityChecks(req, newObj) && - !reflect.DeepEqual(newObj.Spec.Template.Spec, old.Spec.Template.Spec) { - allErrs = append(allErrs, - field.Invalid(field.NewPath("spec", "template", "spec"), r, OpenStackMachineTemplateImmutableMsg), - ) - } - - return aggregateObjErrors(newObj.GroupVersionKind().GroupKind(), newObj.Name, allErrs) -} - -// ValidateDelete implements webhook.CustomValidator so a webhook will be registered for the type. -func (r *OpenStackMachineTemplateWebhook) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) { - return nil, nil -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplatelist_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplatelist_webhook.go deleted file mode 100644 index c1ff00c3..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackmachinetemplatelist_webhook.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - "sigs.k8s.io/controller-runtime/pkg/builder" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// log is for logging in this package. -var _ = logf.Log.WithName("openstackmachinetemplatelist-resource") - -func (r *OpenStackMachineTemplateList) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(r). - Complete() -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types.go index 3ef5305f..c9404cec 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types.go @@ -281,7 +281,7 @@ type LoadBalancer struct { type SecurityGroup struct { Name string `json:"name"` ID string `json:"id"` - Rules []SecurityGroupRule `json:"rules"` + Rules []SecurityGroupRule `json:"rules,omitempty"` } // SecurityGroupRule represent the basic information of the associated OpenStack @@ -315,8 +315,8 @@ func (r SecurityGroupRule) Equal(x SecurityGroupRule) bool { type InstanceState string var ( - // InstanceStateBuilding is the string representing an instance in a building state. - InstanceStateBuilding = InstanceState("BUILDING") + // InstanceStateBuild is the string representing an instance in a build state. + InstanceStateBuild = InstanceState("BUILD") // InstanceStateActive is the string representing an instance in an active state. InstanceStateActive = InstanceState("ACTIVE") @@ -332,6 +332,9 @@ var ( // InstanceStateDeleted is the string representing an instance in a deleted state. InstanceStateDeleted = InstanceState("DELETED") + + // InstanceStateUndefined is the string representing an undefined instance state. + InstanceStateUndefined = InstanceState("") ) // Bastion represents basic information about the bastion node. diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types_conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types_conversion.go new file mode 100644 index 00000000..db640e1e --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/types_conversion.go @@ -0,0 +1,590 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha7 + +import ( + "errors" + + apiconversion "k8s.io/apimachinery/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon" + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" +) + +/* SecurityGroupFilter */ + +func restorev1alpha7SecurityGroupFilter(previous *SecurityGroupFilter, dst *SecurityGroupFilter) { + // The edge cases with multiple commas are too tricky in this direction, + // so we just restore the whole thing. + dst.Tags = previous.Tags + dst.TagsAny = previous.TagsAny + dst.NotTags = previous.NotTags + dst.NotTagsAny = previous.NotTagsAny + + // If ID was set we lost all other filter params + if dst.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + } +} + +func restorev1alpha7SecurityGroup(previous *SecurityGroup, dst *SecurityGroup) { + if previous == nil || dst == nil { + return + } + + dst.Rules = previous.Rules +} + +func restorev1beta1SecurityGroupParam(previous *infrav1.SecurityGroupParam, dst *infrav1.SecurityGroupParam) { + if previous == nil || dst == nil { + return + } + + if dst.Filter != nil && previous.Filter != nil { + dst.Filter.Tags = previous.Filter.Tags + dst.Filter.TagsAny = previous.Filter.TagsAny + dst.Filter.NotTags = previous.Filter.NotTags + dst.Filter.NotTagsAny = previous.Filter.NotTagsAny + } +} + +func Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(in *SecurityGroupFilter, out *infrav1.SecurityGroupParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + + filter := &infrav1.SecurityGroupFilter{} + if err := autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in, filter, s); err != nil { + return err + } + infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &filter.FilterByNeutronTags) + if !filter.IsZero() { + out.Filter = filter + } + return nil +} + +func Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(in *infrav1.SecurityGroupParam, out *SecurityGroupFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter != nil { + if err := autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in.Filter, out, s); err != nil { + return err + } + infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) + } + return nil +} + +/* NetworkFilter */ + +func restorev1alpha7NetworkFilter(previous *NetworkFilter, dst *NetworkFilter) { + if previous == nil || dst == nil { + return + } + + // The edge cases with multiple commas are too tricky in this direction, + // so we just restore the whole thing. + dst.Tags = previous.Tags + dst.TagsAny = previous.TagsAny + dst.NotTags = previous.NotTags + dst.NotTagsAny = previous.NotTagsAny + + // If ID was set we lost all over filter params + if dst.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + } +} + +func restorev1beta1NetworkParam(previous *infrav1.NetworkParam, dst *infrav1.NetworkParam) { + if previous == nil || dst == nil { + return + } + + if dst.Filter != nil && previous.Filter != nil { + dst.Filter.FilterByNeutronTags = previous.Filter.FilterByNeutronTags + } +} + +func Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkParam(in *NetworkFilter, out *infrav1.NetworkParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + outFilter := &infrav1.NetworkFilter{} + if err := autoConvert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(in, outFilter, s); err != nil { + return err + } + infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &outFilter.FilterByNeutronTags) + if !outFilter.IsZero() { + out.Filter = outFilter + } + return nil +} + +func Convert_v1beta1_NetworkParam_To_v1alpha7_NetworkFilter(in *infrav1.NetworkParam, out *NetworkFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter != nil { + if err := autoConvert_v1beta1_NetworkFilter_To_v1alpha7_NetworkFilter(in.Filter, out, s); err != nil { + return err + } + infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) + } + return nil +} + +/* SubnetFilter */ + +func restorev1alpha7SubnetFilter(previous *SubnetFilter, dst *SubnetFilter) { + if previous == nil || dst == nil { + return + } + + // The edge cases with multiple commas are too tricky in this direction, + // so we just restore the whole thing. + dst.Tags = previous.Tags + dst.TagsAny = previous.TagsAny + dst.NotTags = previous.NotTags + dst.NotTagsAny = previous.NotTagsAny + + // If ID was set we will have lost all other fields in up-conversion + if previous.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + dst.IPVersion = previous.IPVersion + dst.GatewayIP = previous.GatewayIP + dst.CIDR = previous.CIDR + dst.IPv6AddressMode = previous.IPv6AddressMode + dst.IPv6RAMode = previous.IPv6RAMode + } +} + +func restorev1beta1SubnetParam(previous *infrav1.SubnetParam, dst *infrav1.SubnetParam) { + if previous == nil || dst == nil { + return + } + + optional.RestoreString(&previous.ID, &dst.ID) + + if previous.Filter != nil && dst.Filter != nil { + dst.Filter.FilterByNeutronTags = previous.Filter.FilterByNeutronTags + } +} + +func Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(in *SubnetFilter, out *infrav1.SubnetParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + + filter := &infrav1.SubnetFilter{} + if err := autoConvert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in, filter, s); err != nil { + return err + } + infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &filter.FilterByNeutronTags) + + if !filter.IsZero() { + out.Filter = filter + } + return nil +} + +func Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(in *infrav1.SubnetParam, out *SubnetFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter == nil { + return nil + } + + if err := autoConvert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in.Filter, out, s); err != nil { + return err + } + infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) + return nil +} + +/* RouterFilter */ + +func restorev1alpha7RouterFilter(previous *RouterFilter, dst *RouterFilter) { + // The edge cases with multiple commas are too tricky in this direction, + // so we just restore the whole thing. + dst.Tags = previous.Tags + dst.TagsAny = previous.TagsAny + dst.NotTags = previous.NotTags + dst.NotTagsAny = previous.NotTagsAny + + // If ID was set we lost all other filter params + if dst.ID != "" { + dst.Name = previous.Name + dst.Description = previous.Description + dst.ProjectID = previous.ProjectID + } +} + +func restorev1beta1RouterParam(previous *infrav1.RouterParam, dst *infrav1.RouterParam) { + if previous == nil || dst == nil { + return + } + + optional.RestoreString(&previous.ID, &dst.ID) + if previous.Filter != nil && dst.Filter != nil { + dst.Filter.FilterByNeutronTags = previous.Filter.FilterByNeutronTags + } +} + +func Convert_v1alpha7_RouterFilter_To_v1beta1_RouterParam(in *RouterFilter, out *infrav1.RouterParam, s apiconversion.Scope) error { + if in.ID != "" { + out.ID = &in.ID + return nil + } + + filter := &infrav1.RouterFilter{} + if err := autoConvert_v1alpha7_RouterFilter_To_v1beta1_RouterFilter(in, filter, s); err != nil { + return err + } + infrav1.ConvertAllTagsTo(in.Tags, in.TagsAny, in.NotTags, in.NotTagsAny, &filter.FilterByNeutronTags) + if !filter.IsZero() { + out.Filter = filter + } + return nil +} + +func Convert_v1beta1_RouterParam_To_v1alpha7_RouterFilter(in *infrav1.RouterParam, out *RouterFilter, s apiconversion.Scope) error { + if in.ID != nil { + out.ID = *in.ID + return nil + } + + if in.Filter != nil { + if err := autoConvert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter(in.Filter, out, s); err != nil { + return err + } + infrav1.ConvertAllTagsFrom(&in.Filter.FilterByNeutronTags, &out.Tags, &out.TagsAny, &out.NotTags, &out.NotTagsAny) + } + return nil +} + +/* PortOpts */ + +func restorev1alpha7Port(previous *PortOpts, dst *PortOpts) { + if len(dst.SecurityGroupFilters) == len(previous.SecurityGroupFilters) { + for i := range dst.SecurityGroupFilters { + restorev1alpha7SecurityGroupFilter(&previous.SecurityGroupFilters[i], &dst.SecurityGroupFilters[i]) + } + } + + if dst.Network != nil && previous.Network != nil { + restorev1alpha7NetworkFilter(previous.Network, dst.Network) + } + + if len(dst.FixedIPs) == len(previous.FixedIPs) { + for i := range dst.FixedIPs { + prevFixedIP := &previous.FixedIPs[i] + dstFixedIP := &dst.FixedIPs[i] + + if dstFixedIP.Subnet != nil && prevFixedIP.Subnet != nil { + restorev1alpha7SubnetFilter(prevFixedIP.Subnet, dstFixedIP.Subnet) + } + } + } +} + +func restorev1beta1Port(previous *infrav1.PortOpts, dst *infrav1.PortOpts) { + restorev1beta1NetworkParam(previous.Network, dst.Network) + + optional.RestoreString(&previous.NameSuffix, &dst.NameSuffix) + optional.RestoreString(&previous.Description, &dst.Description) + optional.RestoreString(&previous.MACAddress, &dst.MACAddress) + + if len(dst.FixedIPs) == len(previous.FixedIPs) { + for j := range dst.FixedIPs { + prevFixedIP := &previous.FixedIPs[j] + dstFixedIP := &dst.FixedIPs[j] + + optional.RestoreString(&prevFixedIP.IPAddress, &dstFixedIP.IPAddress) + restorev1beta1SubnetParam(prevFixedIP.Subnet, dstFixedIP.Subnet) + } + } + + if len(dst.AllowedAddressPairs) == len(previous.AllowedAddressPairs) { + for j := range dst.AllowedAddressPairs { + prevAAP := &previous.AllowedAddressPairs[j] + dstAAP := &dst.AllowedAddressPairs[j] + + optional.RestoreString(&prevAAP.MACAddress, &dstAAP.MACAddress) + } + } + + optional.RestoreString(&previous.HostID, &dst.HostID) + optional.RestoreString(&previous.VNICType, &dst.VNICType) + + if dst.Profile == nil && previous.Profile != nil { + dst.Profile = &infrav1.BindingProfile{} + } + + if dst.Profile != nil && previous.Profile != nil { + dstProfile := dst.Profile + prevProfile := previous.Profile + + if dstProfile.OVSHWOffload == nil || !*dstProfile.OVSHWOffload { + dstProfile.OVSHWOffload = prevProfile.OVSHWOffload + } + + if dstProfile.TrustedVF == nil || !*dstProfile.TrustedVF { + dstProfile.TrustedVF = prevProfile.TrustedVF + } + } + + if len(dst.SecurityGroups) == len(previous.SecurityGroups) { + for j := range dst.SecurityGroups { + restorev1beta1SecurityGroupParam(&previous.SecurityGroups[j], &dst.SecurityGroups[j]) + } + } +} + +func Convert_v1alpha7_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *infrav1.PortOpts, s apiconversion.Scope) error { + if err := autoConvert_v1alpha7_PortOpts_To_v1beta1_PortOpts(in, out, s); err != nil { + return err + } + + // Copy members of ResolvedPortSpecFields + var allowedAddressPairs []infrav1.AddressPair + if len(in.AllowedAddressPairs) > 0 { + allowedAddressPairs = make([]infrav1.AddressPair, len(in.AllowedAddressPairs)) + for i := range in.AllowedAddressPairs { + aap := &in.AllowedAddressPairs[i] + allowedAddressPairs[i] = infrav1.AddressPair{ + MACAddress: &aap.MACAddress, + IPAddress: aap.IPAddress, + } + } + } + var valueSpecs []infrav1.ValueSpec + if len(in.ValueSpecs) > 0 { + valueSpecs = make([]infrav1.ValueSpec, len(in.ValueSpecs)) + for i, vs := range in.ValueSpecs { + valueSpecs[i] = infrav1.ValueSpec(vs) + } + } + out.AdminStateUp = in.AdminStateUp + out.AllowedAddressPairs = allowedAddressPairs + out.DisablePortSecurity = in.DisablePortSecurity + out.PropagateUplinkStatus = in.PropagateUplinkStatus + out.ValueSpecs = valueSpecs + if err := errors.Join( + optional.Convert_string_To_optional_String(&in.MACAddress, &out.MACAddress, s), + optional.Convert_string_To_optional_String(&in.HostID, &out.HostID, s), + optional.Convert_string_To_optional_String(&in.VNICType, &out.VNICType, s), + ); err != nil { + return err + } + + if len(in.SecurityGroupFilters) > 0 { + out.SecurityGroups = make([]infrav1.SecurityGroupParam, len(in.SecurityGroupFilters)) + for i := range in.SecurityGroupFilters { + if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(&in.SecurityGroupFilters[i], &out.SecurityGroups[i], s); err != nil { + return err + } + } + } + + if in.Profile != (BindingProfile{}) { + out.Profile = &infrav1.BindingProfile{} + if err := Convert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile(&in.Profile, out.Profile, s); err != nil { + return err + } + } + + return nil +} + +func Convert_v1beta1_PortOpts_To_v1alpha7_PortOpts(in *infrav1.PortOpts, out *PortOpts, s apiconversion.Scope) error { + if err := autoConvert_v1beta1_PortOpts_To_v1alpha7_PortOpts(in, out, s); err != nil { + return err + } + + // Copy members of ResolvedPortSpecFields + var allowedAddressPairs []AddressPair + if len(in.AllowedAddressPairs) > 0 { + allowedAddressPairs = make([]AddressPair, len(in.AllowedAddressPairs)) + for i := range in.AllowedAddressPairs { + inAAP := &in.AllowedAddressPairs[i] + outAAP := &allowedAddressPairs[i] + if err := optional.Convert_optional_String_To_string(&inAAP.MACAddress, &outAAP.MACAddress, s); err != nil { + return err + } + outAAP.IPAddress = inAAP.IPAddress + } + } + var valueSpecs []ValueSpec + if len(in.ValueSpecs) > 0 { + valueSpecs = make([]ValueSpec, len(in.ValueSpecs)) + for i, vs := range in.ValueSpecs { + valueSpecs[i] = ValueSpec(vs) + } + } + out.AdminStateUp = in.AdminStateUp + out.AllowedAddressPairs = allowedAddressPairs + out.DisablePortSecurity = in.DisablePortSecurity + out.PropagateUplinkStatus = in.PropagateUplinkStatus + out.ValueSpecs = valueSpecs + if err := errors.Join( + optional.Convert_optional_String_To_string(&in.MACAddress, &out.MACAddress, s), + optional.Convert_optional_String_To_string(&in.HostID, &out.HostID, s), + optional.Convert_optional_String_To_string(&in.VNICType, &out.VNICType, s), + ); err != nil { + return err + } + + if len(in.SecurityGroups) > 0 { + out.SecurityGroupFilters = make([]SecurityGroupFilter, len(in.SecurityGroups)) + for i := range in.SecurityGroups { + if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(&in.SecurityGroups[i], &out.SecurityGroupFilters[i], s); err != nil { + return err + } + } + } + + if in.Profile != nil { + if err := Convert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile(in.Profile, &out.Profile, s); err != nil { + return err + } + } + + return nil +} + +/* RootVolume */ + +func restorev1beta1BlockDeviceVolume(previous *infrav1.BlockDeviceVolume, dst *infrav1.BlockDeviceVolume) { + if previous == nil || dst == nil { + return + } + + dstAZ := dst.AvailabilityZone + previousAZ := previous.AvailabilityZone + + // Empty From (the default) will be converted to the explicit "Name" + if dstAZ != nil && previousAZ != nil && dstAZ.From == "Name" { + dstAZ.From = previousAZ.From + } +} + +func Convert_v1alpha7_RootVolume_To_v1beta1_RootVolume(in *RootVolume, out *infrav1.RootVolume, s apiconversion.Scope) error { + out.SizeGiB = in.Size + out.Type = in.VolumeType + return conversioncommon.Convert_string_To_Pointer_v1beta1_VolumeAvailabilityZone(&in.AvailabilityZone, &out.AvailabilityZone, s) +} + +func Convert_v1beta1_RootVolume_To_v1alpha7_RootVolume(in *infrav1.RootVolume, out *RootVolume, s apiconversion.Scope) error { + out.Size = in.SizeGiB + out.VolumeType = in.Type + return conversioncommon.Convert_Pointer_v1beta1_VolumeAvailabilityZone_To_string(&in.AvailabilityZone, &out.AvailabilityZone, s) +} + +/* SecurityGroup */ + +func Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(in *SecurityGroup, out *infrav1.SecurityGroupStatus, _ apiconversion.Scope) error { + out.ID = in.ID + out.Name = in.Name + + return nil +} + +func Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(in *infrav1.SecurityGroupStatus, out *SecurityGroup, _ apiconversion.Scope) error { + out.ID = in.ID + out.Name = in.Name + return nil +} + +/* OpenStackIdentityReference */ + +func Convert_v1alpha7_OpenStackIdentityReference_To_v1beta1_OpenStackIdentityReference(in *OpenStackIdentityReference, out *infrav1.OpenStackIdentityReference, s apiconversion.Scope) error { + return autoConvert_v1alpha7_OpenStackIdentityReference_To_v1beta1_OpenStackIdentityReference(in, out, s) +} + +func Convert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityReference(in *infrav1.OpenStackIdentityReference, out *OpenStackIdentityReference, _ apiconversion.Scope) error { + out.Name = in.Name + // Kind will be overwritten during restore if it was previously set to some other value, but if not then some value is still required + out.Kind = "Secret" + return nil +} + +/* APIServerLoadBalancer */ + +func restorev1beta1APIServerLoadBalancer(previous *infrav1.APIServerLoadBalancer, dst *infrav1.APIServerLoadBalancer) { + if dst == nil || previous == nil { + return + } + + // AZ doesn't exist in v1alpha6, so always restore. + dst.AvailabilityZone = previous.AvailabilityZone +} + +/* Placeholders */ + +// conversion-gen registers these functions so we must provider stubs, but +// nothing should ever call them + +func Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(_ *SubnetFilter, _ *infrav1.SubnetFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter should not be called") +} + +func Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(_ *infrav1.SubnetFilter, _ *SubnetFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter should not be called") +} + +func Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(_ *NetworkFilter, _ *infrav1.NetworkFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1alpha6_NetworkFilter_To_v1beta1_NetworkFilter should not be called") +} + +func Convert_v1beta1_NetworkFilter_To_v1alpha7_NetworkFilter(_ *infrav1.NetworkFilter, _ *NetworkFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1beta1_NetworkFilter_To_v1alpha6_NetworkFilter should not be called") +} + +func Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(_ *SecurityGroupFilter, _ *infrav1.SecurityGroupFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter should not be called") +} + +func Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(_ *infrav1.SecurityGroupFilter, _ *SecurityGroupFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter should not be called") +} + +func Convert_v1alpha7_RouterFilter_To_v1beta1_RouterFilter(_ *RouterFilter, _ *infrav1.RouterFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1alpha7_RouterFilter_To_v1beta1_RouterFilter should not be called") +} + +func Convert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter(_ *infrav1.RouterFilter, _ *RouterFilter, _ apiconversion.Scope) error { + return errors.New("Convert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter should not be called") +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/webhooks.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/webhooks.go deleted file mode 100644 index d58fdbb1..00000000 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/webhooks.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha7 - -import ( - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/validation/field" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func aggregateObjErrors(gk schema.GroupKind, name string, allErrs field.ErrorList) (admission.Warnings, error) { - if len(allErrs) == 0 { - return nil, nil - } - - return nil, apierrors.NewInvalid( - gk, - name, - allErrs, - ) -} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.conversion.go new file mode 100644 index 00000000..a4144215 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.conversion.go @@ -0,0 +1,1902 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha7 + +import ( + unsafe "unsafe" + + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + v1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" + conversioncommon "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon" + optional "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + errors "sigs.k8s.io/cluster-api/errors" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*AdditionalBlockDevice)(nil), (*v1beta1.AdditionalBlockDevice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice(a.(*AdditionalBlockDevice), b.(*v1beta1.AdditionalBlockDevice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.AdditionalBlockDevice)(nil), (*AdditionalBlockDevice)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice(a.(*v1beta1.AdditionalBlockDevice), b.(*AdditionalBlockDevice), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AddressPair)(nil), (*v1beta1.AddressPair)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_AddressPair_To_v1beta1_AddressPair(a.(*AddressPair), b.(*v1beta1.AddressPair), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.AddressPair)(nil), (*AddressPair)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_AddressPair_To_v1alpha7_AddressPair(a.(*v1beta1.AddressPair), b.(*AddressPair), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BastionStatus)(nil), (*v1beta1.BastionStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus(a.(*BastionStatus), b.(*v1beta1.BastionStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BindingProfile)(nil), (*v1beta1.BindingProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile(a.(*BindingProfile), b.(*v1beta1.BindingProfile), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BindingProfile)(nil), (*BindingProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile(a.(*v1beta1.BindingProfile), b.(*BindingProfile), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BlockDeviceStorage)(nil), (*v1beta1.BlockDeviceStorage)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage(a.(*BlockDeviceStorage), b.(*v1beta1.BlockDeviceStorage), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BlockDeviceStorage)(nil), (*BlockDeviceStorage)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage(a.(*v1beta1.BlockDeviceStorage), b.(*BlockDeviceStorage), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BlockDeviceVolume)(nil), (*v1beta1.BlockDeviceVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume(a.(*BlockDeviceVolume), b.(*v1beta1.BlockDeviceVolume), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BlockDeviceVolume)(nil), (*BlockDeviceVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(a.(*v1beta1.BlockDeviceVolume), b.(*BlockDeviceVolume), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExternalRouterIPParam)(nil), (*v1beta1.ExternalRouterIPParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(a.(*ExternalRouterIPParam), b.(*v1beta1.ExternalRouterIPParam), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ExternalRouterIPParam)(nil), (*ExternalRouterIPParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(a.(*v1beta1.ExternalRouterIPParam), b.(*ExternalRouterIPParam), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*FixedIP)(nil), (*v1beta1.FixedIP)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_FixedIP_To_v1beta1_FixedIP(a.(*FixedIP), b.(*v1beta1.FixedIP), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.FixedIP)(nil), (*FixedIP)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_FixedIP_To_v1alpha7_FixedIP(a.(*v1beta1.FixedIP), b.(*FixedIP), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LoadBalancer)(nil), (*v1beta1.LoadBalancer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer(a.(*LoadBalancer), b.(*v1beta1.LoadBalancer), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*NetworkStatus)(nil), (*v1beta1.NetworkStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus(a.(*NetworkStatus), b.(*v1beta1.NetworkStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.NetworkStatus)(nil), (*NetworkStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus(a.(*v1beta1.NetworkStatus), b.(*NetworkStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*NetworkStatusWithSubnets)(nil), (*v1beta1.NetworkStatusWithSubnets)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_NetworkStatusWithSubnets_To_v1beta1_NetworkStatusWithSubnets(a.(*NetworkStatusWithSubnets), b.(*v1beta1.NetworkStatusWithSubnets), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.NetworkStatusWithSubnets)(nil), (*NetworkStatusWithSubnets)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkStatusWithSubnets_To_v1alpha7_NetworkStatusWithSubnets(a.(*v1beta1.NetworkStatusWithSubnets), b.(*NetworkStatusWithSubnets), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackCluster)(nil), (*v1beta1.OpenStackCluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster(a.(*OpenStackCluster), b.(*v1beta1.OpenStackCluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackCluster)(nil), (*OpenStackCluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster(a.(*v1beta1.OpenStackCluster), b.(*OpenStackCluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterList)(nil), (*v1beta1.OpenStackClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList(a.(*OpenStackClusterList), b.(*v1beta1.OpenStackClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackClusterList)(nil), (*OpenStackClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList(a.(*v1beta1.OpenStackClusterList), b.(*OpenStackClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterStatus)(nil), (*v1beta1.OpenStackClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus(a.(*OpenStackClusterStatus), b.(*v1beta1.OpenStackClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterTemplate)(nil), (*v1beta1.OpenStackClusterTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate(a.(*OpenStackClusterTemplate), b.(*v1beta1.OpenStackClusterTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackClusterTemplate)(nil), (*OpenStackClusterTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate(a.(*v1beta1.OpenStackClusterTemplate), b.(*OpenStackClusterTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterTemplateList)(nil), (*v1beta1.OpenStackClusterTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList(a.(*OpenStackClusterTemplateList), b.(*v1beta1.OpenStackClusterTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackClusterTemplateList)(nil), (*OpenStackClusterTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList(a.(*v1beta1.OpenStackClusterTemplateList), b.(*OpenStackClusterTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterTemplateResource)(nil), (*v1beta1.OpenStackClusterTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource(a.(*OpenStackClusterTemplateResource), b.(*v1beta1.OpenStackClusterTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackClusterTemplateResource)(nil), (*OpenStackClusterTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource(a.(*v1beta1.OpenStackClusterTemplateResource), b.(*OpenStackClusterTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackClusterTemplateSpec)(nil), (*v1beta1.OpenStackClusterTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec(a.(*OpenStackClusterTemplateSpec), b.(*v1beta1.OpenStackClusterTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackClusterTemplateSpec)(nil), (*OpenStackClusterTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec(a.(*v1beta1.OpenStackClusterTemplateSpec), b.(*OpenStackClusterTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineList)(nil), (*v1beta1.OpenStackMachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList(a.(*OpenStackMachineList), b.(*v1beta1.OpenStackMachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackMachineList)(nil), (*OpenStackMachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList(a.(*v1beta1.OpenStackMachineList), b.(*OpenStackMachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineStatus)(nil), (*v1beta1.OpenStackMachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus(a.(*OpenStackMachineStatus), b.(*v1beta1.OpenStackMachineStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineTemplate)(nil), (*v1beta1.OpenStackMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate(a.(*OpenStackMachineTemplate), b.(*v1beta1.OpenStackMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackMachineTemplate)(nil), (*OpenStackMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate(a.(*v1beta1.OpenStackMachineTemplate), b.(*OpenStackMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineTemplateList)(nil), (*v1beta1.OpenStackMachineTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList(a.(*OpenStackMachineTemplateList), b.(*v1beta1.OpenStackMachineTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackMachineTemplateList)(nil), (*OpenStackMachineTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList(a.(*v1beta1.OpenStackMachineTemplateList), b.(*OpenStackMachineTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineTemplateResource)(nil), (*v1beta1.OpenStackMachineTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource(a.(*OpenStackMachineTemplateResource), b.(*v1beta1.OpenStackMachineTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackMachineTemplateResource)(nil), (*OpenStackMachineTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource(a.(*v1beta1.OpenStackMachineTemplateResource), b.(*OpenStackMachineTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*OpenStackMachineTemplateSpec)(nil), (*v1beta1.OpenStackMachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec(a.(*OpenStackMachineTemplateSpec), b.(*v1beta1.OpenStackMachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.OpenStackMachineTemplateSpec)(nil), (*OpenStackMachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec(a.(*v1beta1.OpenStackMachineTemplateSpec), b.(*OpenStackMachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Router)(nil), (*v1beta1.Router)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_Router_To_v1beta1_Router(a.(*Router), b.(*v1beta1.Router), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Router)(nil), (*Router)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Router_To_v1alpha7_Router(a.(*v1beta1.Router), b.(*Router), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Subnet)(nil), (*v1beta1.Subnet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_Subnet_To_v1beta1_Subnet(a.(*Subnet), b.(*v1beta1.Subnet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Subnet)(nil), (*Subnet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Subnet_To_v1alpha7_Subnet(a.(*v1beta1.Subnet), b.(*Subnet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ValueSpec)(nil), (*v1beta1.ValueSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_ValueSpec_To_v1beta1_ValueSpec(a.(*ValueSpec), b.(*v1beta1.ValueSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ValueSpec)(nil), (*ValueSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ValueSpec_To_v1alpha7_ValueSpec(a.(*v1beta1.ValueSpec), b.(*ValueSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*APIServerLoadBalancer)(nil), (*v1beta1.APIServerLoadBalancer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_APIServerLoadBalancer_To_v1beta1_APIServerLoadBalancer(a.(*APIServerLoadBalancer), b.(*v1beta1.APIServerLoadBalancer), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*Bastion)(nil), (*v1beta1.Bastion)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_Bastion_To_v1beta1_Bastion(a.(*Bastion), b.(*v1beta1.Bastion), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*NetworkFilter)(nil), (*v1beta1.NetworkFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(a.(*NetworkFilter), b.(*v1beta1.NetworkFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*NetworkFilter)(nil), (*v1beta1.NetworkParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkParam(a.(*NetworkFilter), b.(*v1beta1.NetworkParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*OpenStackClusterSpec)(nil), (*v1beta1.OpenStackClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(a.(*OpenStackClusterSpec), b.(*v1beta1.OpenStackClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*OpenStackIdentityReference)(nil), (*v1beta1.OpenStackIdentityReference)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackIdentityReference_To_v1beta1_OpenStackIdentityReference(a.(*OpenStackIdentityReference), b.(*v1beta1.OpenStackIdentityReference), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*OpenStackMachineSpec)(nil), (*v1beta1.OpenStackMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(a.(*OpenStackMachineSpec), b.(*v1beta1.OpenStackMachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*OpenStackMachine)(nil), (*v1beta1.OpenStackMachine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine(a.(*OpenStackMachine), b.(*v1beta1.OpenStackMachine), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*PortOpts)(nil), (*v1beta1.PortOpts)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_PortOpts_To_v1beta1_PortOpts(a.(*PortOpts), b.(*v1beta1.PortOpts), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*RootVolume)(nil), (*v1beta1.RootVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_RootVolume_To_v1beta1_RootVolume(a.(*RootVolume), b.(*v1beta1.RootVolume), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*RouterFilter)(nil), (*v1beta1.RouterFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_RouterFilter_To_v1beta1_RouterFilter(a.(*RouterFilter), b.(*v1beta1.RouterFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*RouterFilter)(nil), (*v1beta1.RouterParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_RouterFilter_To_v1beta1_RouterParam(a.(*RouterFilter), b.(*v1beta1.RouterParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SecurityGroupFilter)(nil), (*v1beta1.SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(a.(*SecurityGroupFilter), b.(*v1beta1.SecurityGroupFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SecurityGroupFilter)(nil), (*v1beta1.SecurityGroupParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(a.(*SecurityGroupFilter), b.(*v1beta1.SecurityGroupParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SecurityGroup)(nil), (*v1beta1.SecurityGroupStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(a.(*SecurityGroup), b.(*v1beta1.SecurityGroupStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SubnetFilter)(nil), (*v1beta1.SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(a.(*SubnetFilter), b.(*v1beta1.SubnetFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*SubnetFilter)(nil), (*v1beta1.SubnetParam)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(a.(*SubnetFilter), b.(*v1beta1.SubnetParam), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.APIServerLoadBalancer)(nil), (*APIServerLoadBalancer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIServerLoadBalancer_To_v1alpha7_APIServerLoadBalancer(a.(*v1beta1.APIServerLoadBalancer), b.(*APIServerLoadBalancer), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.BastionStatus)(nil), (*BastionStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(a.(*v1beta1.BastionStatus), b.(*BastionStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.Bastion)(nil), (*Bastion)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Bastion_To_v1alpha7_Bastion(a.(*v1beta1.Bastion), b.(*Bastion), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.LoadBalancer)(nil), (*LoadBalancer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_LoadBalancer_To_v1alpha7_LoadBalancer(a.(*v1beta1.LoadBalancer), b.(*LoadBalancer), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.NetworkFilter)(nil), (*NetworkFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkFilter_To_v1alpha7_NetworkFilter(a.(*v1beta1.NetworkFilter), b.(*NetworkFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.NetworkParam)(nil), (*NetworkFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkParam_To_v1alpha7_NetworkFilter(a.(*v1beta1.NetworkParam), b.(*NetworkFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackClusterSpec)(nil), (*OpenStackClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(a.(*v1beta1.OpenStackClusterSpec), b.(*OpenStackClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackClusterStatus)(nil), (*OpenStackClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(a.(*v1beta1.OpenStackClusterStatus), b.(*OpenStackClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackIdentityReference)(nil), (*OpenStackIdentityReference)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityReference(a.(*v1beta1.OpenStackIdentityReference), b.(*OpenStackIdentityReference), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackMachineSpec)(nil), (*OpenStackMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(a.(*v1beta1.OpenStackMachineSpec), b.(*OpenStackMachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackMachineStatus)(nil), (*OpenStackMachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachineStatus_To_v1alpha7_OpenStackMachineStatus(a.(*v1beta1.OpenStackMachineStatus), b.(*OpenStackMachineStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.OpenStackMachine)(nil), (*OpenStackMachine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine(a.(*v1beta1.OpenStackMachine), b.(*OpenStackMachine), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.PortOpts)(nil), (*PortOpts)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_PortOpts_To_v1alpha7_PortOpts(a.(*v1beta1.PortOpts), b.(*PortOpts), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.RootVolume)(nil), (*RootVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RootVolume_To_v1alpha7_RootVolume(a.(*v1beta1.RootVolume), b.(*RootVolume), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.RouterFilter)(nil), (*RouterFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter(a.(*v1beta1.RouterFilter), b.(*RouterFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.RouterParam)(nil), (*RouterFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RouterParam_To_v1alpha7_RouterFilter(a.(*v1beta1.RouterParam), b.(*RouterFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SecurityGroupFilter)(nil), (*SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(a.(*v1beta1.SecurityGroupFilter), b.(*SecurityGroupFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SecurityGroupParam)(nil), (*SecurityGroupFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(a.(*v1beta1.SecurityGroupParam), b.(*SecurityGroupFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SecurityGroupStatus)(nil), (*SecurityGroup)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(a.(*v1beta1.SecurityGroupStatus), b.(*SecurityGroup), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SubnetFilter)(nil), (*SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(a.(*v1beta1.SubnetFilter), b.(*SubnetFilter), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.SubnetParam)(nil), (*SubnetFilter)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(a.(*v1beta1.SubnetParam), b.(*SubnetFilter), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha7_APIServerLoadBalancer_To_v1beta1_APIServerLoadBalancer(in *APIServerLoadBalancer, out *v1beta1.APIServerLoadBalancer, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { + return err + } + out.AdditionalPorts = *(*[]int)(unsafe.Pointer(&in.AdditionalPorts)) + out.AllowedCIDRs = *(*[]string)(unsafe.Pointer(&in.AllowedCIDRs)) + if err := optional.Convert_string_To_optional_String(&in.Provider, &out.Provider, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_APIServerLoadBalancer_To_v1alpha7_APIServerLoadBalancer(in *v1beta1.APIServerLoadBalancer, out *APIServerLoadBalancer, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + return err + } + out.AdditionalPorts = *(*[]int)(unsafe.Pointer(&in.AdditionalPorts)) + out.AllowedCIDRs = *(*[]string)(unsafe.Pointer(&in.AllowedCIDRs)) + if err := optional.Convert_optional_String_To_string(&in.Provider, &out.Provider, s); err != nil { + return err + } + // WARNING: in.Network requires manual conversion: does not exist in peer-type + // WARNING: in.Subnets requires manual conversion: does not exist in peer-type + // WARNING: in.AvailabilityZone requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice(in *AdditionalBlockDevice, out *v1beta1.AdditionalBlockDevice, s conversion.Scope) error { + out.Name = in.Name + out.SizeGiB = in.SizeGiB + if err := Convert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage(&in.Storage, &out.Storage, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice is an autogenerated conversion function. +func Convert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice(in *AdditionalBlockDevice, out *v1beta1.AdditionalBlockDevice, s conversion.Scope) error { + return autoConvert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice(in, out, s) +} + +func autoConvert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice(in *v1beta1.AdditionalBlockDevice, out *AdditionalBlockDevice, s conversion.Scope) error { + out.Name = in.Name + out.SizeGiB = in.SizeGiB + if err := Convert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage(&in.Storage, &out.Storage, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice is an autogenerated conversion function. +func Convert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice(in *v1beta1.AdditionalBlockDevice, out *AdditionalBlockDevice, s conversion.Scope) error { + return autoConvert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice(in, out, s) +} + +func autoConvert_v1alpha7_AddressPair_To_v1beta1_AddressPair(in *AddressPair, out *v1beta1.AddressPair, s conversion.Scope) error { + out.IPAddress = in.IPAddress + if err := optional.Convert_string_To_optional_String(&in.MACAddress, &out.MACAddress, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_AddressPair_To_v1beta1_AddressPair is an autogenerated conversion function. +func Convert_v1alpha7_AddressPair_To_v1beta1_AddressPair(in *AddressPair, out *v1beta1.AddressPair, s conversion.Scope) error { + return autoConvert_v1alpha7_AddressPair_To_v1beta1_AddressPair(in, out, s) +} + +func autoConvert_v1beta1_AddressPair_To_v1alpha7_AddressPair(in *v1beta1.AddressPair, out *AddressPair, s conversion.Scope) error { + out.IPAddress = in.IPAddress + if err := optional.Convert_optional_String_To_string(&in.MACAddress, &out.MACAddress, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_AddressPair_To_v1alpha7_AddressPair is an autogenerated conversion function. +func Convert_v1beta1_AddressPair_To_v1alpha7_AddressPair(in *v1beta1.AddressPair, out *AddressPair, s conversion.Scope) error { + return autoConvert_v1beta1_AddressPair_To_v1alpha7_AddressPair(in, out, s) +} + +func autoConvert_v1alpha7_Bastion_To_v1beta1_Bastion(in *Bastion, out *v1beta1.Bastion, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.Enabled, &out.Enabled, s); err != nil { + return err + } + // WARNING: in.Instance requires manual conversion: does not exist in peer-type + if err := optional.Convert_string_To_optional_String(&in.AvailabilityZone, &out.AvailabilityZone, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_Bastion_To_v1alpha7_Bastion(in *v1beta1.Bastion, out *Bastion, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.Enabled, &out.Enabled, s); err != nil { + return err + } + // WARNING: in.Spec requires manual conversion: does not exist in peer-type + if err := optional.Convert_optional_String_To_string(&in.AvailabilityZone, &out.AvailabilityZone, s); err != nil { + return err + } + // WARNING: in.FloatingIP requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus(in *BastionStatus, out *v1beta1.BastionStatus, s conversion.Scope) error { + out.ID = in.ID + out.Name = in.Name + out.SSHKeyName = in.SSHKeyName + out.State = v1beta1.InstanceState(in.State) + out.IP = in.IP + out.FloatingIP = in.FloatingIP + return nil +} + +// Convert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus is an autogenerated conversion function. +func Convert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus(in *BastionStatus, out *v1beta1.BastionStatus, s conversion.Scope) error { + return autoConvert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus(in, out, s) +} + +func autoConvert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(in *v1beta1.BastionStatus, out *BastionStatus, s conversion.Scope) error { + out.ID = in.ID + out.Name = in.Name + out.SSHKeyName = in.SSHKeyName + out.State = InstanceState(in.State) + out.IP = in.IP + out.FloatingIP = in.FloatingIP + // WARNING: in.Resolved requires manual conversion: does not exist in peer-type + // WARNING: in.Resources requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile(in *BindingProfile, out *v1beta1.BindingProfile, s conversion.Scope) error { + if err := v1.Convert_bool_To_Pointer_bool(&in.OVSHWOffload, &out.OVSHWOffload, s); err != nil { + return err + } + if err := v1.Convert_bool_To_Pointer_bool(&in.TrustedVF, &out.TrustedVF, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile is an autogenerated conversion function. +func Convert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile(in *BindingProfile, out *v1beta1.BindingProfile, s conversion.Scope) error { + return autoConvert_v1alpha7_BindingProfile_To_v1beta1_BindingProfile(in, out, s) +} + +func autoConvert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile(in *v1beta1.BindingProfile, out *BindingProfile, s conversion.Scope) error { + if err := v1.Convert_Pointer_bool_To_bool(&in.OVSHWOffload, &out.OVSHWOffload, s); err != nil { + return err + } + if err := v1.Convert_Pointer_bool_To_bool(&in.TrustedVF, &out.TrustedVF, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile is an autogenerated conversion function. +func Convert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile(in *v1beta1.BindingProfile, out *BindingProfile, s conversion.Scope) error { + return autoConvert_v1beta1_BindingProfile_To_v1alpha7_BindingProfile(in, out, s) +} + +func autoConvert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage(in *BlockDeviceStorage, out *v1beta1.BlockDeviceStorage, s conversion.Scope) error { + out.Type = v1beta1.BlockDeviceType(in.Type) + if in.Volume != nil { + in, out := &in.Volume, &out.Volume + *out = new(v1beta1.BlockDeviceVolume) + if err := Convert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume(*in, *out, s); err != nil { + return err + } + } else { + out.Volume = nil + } + return nil +} + +// Convert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage is an autogenerated conversion function. +func Convert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage(in *BlockDeviceStorage, out *v1beta1.BlockDeviceStorage, s conversion.Scope) error { + return autoConvert_v1alpha7_BlockDeviceStorage_To_v1beta1_BlockDeviceStorage(in, out, s) +} + +func autoConvert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage(in *v1beta1.BlockDeviceStorage, out *BlockDeviceStorage, s conversion.Scope) error { + out.Type = BlockDeviceType(in.Type) + if in.Volume != nil { + in, out := &in.Volume, &out.Volume + *out = new(BlockDeviceVolume) + if err := Convert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(*in, *out, s); err != nil { + return err + } + } else { + out.Volume = nil + } + return nil +} + +// Convert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage is an autogenerated conversion function. +func Convert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage(in *v1beta1.BlockDeviceStorage, out *BlockDeviceStorage, s conversion.Scope) error { + return autoConvert_v1beta1_BlockDeviceStorage_To_v1alpha7_BlockDeviceStorage(in, out, s) +} + +func autoConvert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume(in *BlockDeviceVolume, out *v1beta1.BlockDeviceVolume, s conversion.Scope) error { + out.Type = in.Type + if err := conversioncommon.Convert_string_To_Pointer_v1beta1_VolumeAvailabilityZone(&in.AvailabilityZone, &out.AvailabilityZone, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume is an autogenerated conversion function. +func Convert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume(in *BlockDeviceVolume, out *v1beta1.BlockDeviceVolume, s conversion.Scope) error { + return autoConvert_v1alpha7_BlockDeviceVolume_To_v1beta1_BlockDeviceVolume(in, out, s) +} + +func autoConvert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(in *v1beta1.BlockDeviceVolume, out *BlockDeviceVolume, s conversion.Scope) error { + out.Type = in.Type + if err := conversioncommon.Convert_Pointer_v1beta1_VolumeAvailabilityZone_To_string(&in.AvailabilityZone, &out.AvailabilityZone, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume is an autogenerated conversion function. +func Convert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(in *v1beta1.BlockDeviceVolume, out *BlockDeviceVolume, s conversion.Scope) error { + return autoConvert_v1beta1_BlockDeviceVolume_To_v1alpha7_BlockDeviceVolume(in, out, s) +} + +func autoConvert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in *ExternalRouterIPParam, out *v1beta1.ExternalRouterIPParam, s conversion.Scope) error { + out.FixedIP = in.FixedIP + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(&in.Subnet, &out.Subnet, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam is an autogenerated conversion function. +func Convert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in *ExternalRouterIPParam, out *v1beta1.ExternalRouterIPParam, s conversion.Scope) error { + return autoConvert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(in, out, s) +} + +func autoConvert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(in *v1beta1.ExternalRouterIPParam, out *ExternalRouterIPParam, s conversion.Scope) error { + out.FixedIP = in.FixedIP + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(&in.Subnet, &out.Subnet, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam is an autogenerated conversion function. +func Convert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(in *v1beta1.ExternalRouterIPParam, out *ExternalRouterIPParam, s conversion.Scope) error { + return autoConvert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(in, out, s) +} + +func autoConvert_v1alpha7_FixedIP_To_v1beta1_FixedIP(in *FixedIP, out *v1beta1.FixedIP, s conversion.Scope) error { + if in.Subnet != nil { + in, out := &in.Subnet, &out.Subnet + *out = new(v1beta1.SubnetParam) + if err := Convert_v1alpha7_SubnetFilter_To_v1beta1_SubnetParam(*in, *out, s); err != nil { + return err + } + } else { + out.Subnet = nil + } + if err := optional.Convert_string_To_optional_String(&in.IPAddress, &out.IPAddress, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_FixedIP_To_v1beta1_FixedIP is an autogenerated conversion function. +func Convert_v1alpha7_FixedIP_To_v1beta1_FixedIP(in *FixedIP, out *v1beta1.FixedIP, s conversion.Scope) error { + return autoConvert_v1alpha7_FixedIP_To_v1beta1_FixedIP(in, out, s) +} + +func autoConvert_v1beta1_FixedIP_To_v1alpha7_FixedIP(in *v1beta1.FixedIP, out *FixedIP, s conversion.Scope) error { + if in.Subnet != nil { + in, out := &in.Subnet, &out.Subnet + *out = new(SubnetFilter) + if err := Convert_v1beta1_SubnetParam_To_v1alpha7_SubnetFilter(*in, *out, s); err != nil { + return err + } + } else { + out.Subnet = nil + } + if err := optional.Convert_optional_String_To_string(&in.IPAddress, &out.IPAddress, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_FixedIP_To_v1alpha7_FixedIP is an autogenerated conversion function. +func Convert_v1beta1_FixedIP_To_v1alpha7_FixedIP(in *v1beta1.FixedIP, out *FixedIP, s conversion.Scope) error { + return autoConvert_v1beta1_FixedIP_To_v1alpha7_FixedIP(in, out, s) +} + +func autoConvert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer(in *LoadBalancer, out *v1beta1.LoadBalancer, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.IP = in.IP + out.InternalIP = in.InternalIP + out.AllowedCIDRs = *(*[]string)(unsafe.Pointer(&in.AllowedCIDRs)) + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + return nil +} + +// Convert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer is an autogenerated conversion function. +func Convert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer(in *LoadBalancer, out *v1beta1.LoadBalancer, s conversion.Scope) error { + return autoConvert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer(in, out, s) +} + +func autoConvert_v1beta1_LoadBalancer_To_v1alpha7_LoadBalancer(in *v1beta1.LoadBalancer, out *LoadBalancer, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.IP = in.IP + out.InternalIP = in.InternalIP + out.AllowedCIDRs = *(*[]string)(unsafe.Pointer(&in.AllowedCIDRs)) + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.LoadBalancerNetwork requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_NetworkFilter_To_v1beta1_NetworkFilter(in *NetworkFilter, out *v1beta1.NetworkFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.ID requires manual conversion: does not exist in peer-type + // WARNING: in.Tags requires manual conversion: does not exist in peer-type + // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type + // WARNING: in.NotTags requires manual conversion: does not exist in peer-type + // WARNING: in.NotTagsAny requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_NetworkFilter_To_v1alpha7_NetworkFilter(in *v1beta1.NetworkFilter, out *NetworkFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus(in *NetworkStatus, out *v1beta1.NetworkStatus, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + return nil +} + +// Convert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus is an autogenerated conversion function. +func Convert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus(in *NetworkStatus, out *v1beta1.NetworkStatus, s conversion.Scope) error { + return autoConvert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus(in, out, s) +} + +func autoConvert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus(in *v1beta1.NetworkStatus, out *NetworkStatus, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + return nil +} + +// Convert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus is an autogenerated conversion function. +func Convert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus(in *v1beta1.NetworkStatus, out *NetworkStatus, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus(in, out, s) +} + +func autoConvert_v1alpha7_NetworkStatusWithSubnets_To_v1beta1_NetworkStatusWithSubnets(in *NetworkStatusWithSubnets, out *v1beta1.NetworkStatusWithSubnets, s conversion.Scope) error { + if err := Convert_v1alpha7_NetworkStatus_To_v1beta1_NetworkStatus(&in.NetworkStatus, &out.NetworkStatus, s); err != nil { + return err + } + out.Subnets = *(*[]v1beta1.Subnet)(unsafe.Pointer(&in.Subnets)) + return nil +} + +// Convert_v1alpha7_NetworkStatusWithSubnets_To_v1beta1_NetworkStatusWithSubnets is an autogenerated conversion function. +func Convert_v1alpha7_NetworkStatusWithSubnets_To_v1beta1_NetworkStatusWithSubnets(in *NetworkStatusWithSubnets, out *v1beta1.NetworkStatusWithSubnets, s conversion.Scope) error { + return autoConvert_v1alpha7_NetworkStatusWithSubnets_To_v1beta1_NetworkStatusWithSubnets(in, out, s) +} + +func autoConvert_v1beta1_NetworkStatusWithSubnets_To_v1alpha7_NetworkStatusWithSubnets(in *v1beta1.NetworkStatusWithSubnets, out *NetworkStatusWithSubnets, s conversion.Scope) error { + if err := Convert_v1beta1_NetworkStatus_To_v1alpha7_NetworkStatus(&in.NetworkStatus, &out.NetworkStatus, s); err != nil { + return err + } + out.Subnets = *(*[]Subnet)(unsafe.Pointer(&in.Subnets)) + return nil +} + +// Convert_v1beta1_NetworkStatusWithSubnets_To_v1alpha7_NetworkStatusWithSubnets is an autogenerated conversion function. +func Convert_v1beta1_NetworkStatusWithSubnets_To_v1alpha7_NetworkStatusWithSubnets(in *v1beta1.NetworkStatusWithSubnets, out *NetworkStatusWithSubnets, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkStatusWithSubnets_To_v1alpha7_NetworkStatusWithSubnets(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster(in *OpenStackCluster, out *v1beta1.OpenStackCluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster(in *OpenStackCluster, out *v1beta1.OpenStackCluster, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster(in, out, s) +} + +func autoConvert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster(in *v1beta1.OpenStackCluster, out *OpenStackCluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster is an autogenerated conversion function. +func Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster(in *v1beta1.OpenStackCluster, out *OpenStackCluster, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList(in *OpenStackClusterList, out *v1beta1.OpenStackClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.OpenStackCluster, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_OpenStackCluster_To_v1beta1_OpenStackCluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList(in *OpenStackClusterList, out *v1beta1.OpenStackClusterList, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterList_To_v1beta1_OpenStackClusterList(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList(in *v1beta1.OpenStackClusterList, out *OpenStackClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackCluster, len(*in)) + for i := range *in { + if err := Convert_v1beta1_OpenStackCluster_To_v1alpha7_OpenStackCluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList is an autogenerated conversion function. +func Convert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList(in *v1beta1.OpenStackClusterList, out *OpenStackClusterList, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterList_To_v1alpha7_OpenStackClusterList(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(in *OpenStackClusterSpec, out *v1beta1.OpenStackClusterSpec, s conversion.Scope) error { + // WARNING: in.CloudName requires manual conversion: does not exist in peer-type + // WARNING: in.NodeCIDR requires manual conversion: does not exist in peer-type + if in.Router != nil { + in, out := &in.Router, &out.Router + *out = new(v1beta1.RouterParam) + if err := Convert_v1alpha7_RouterFilter_To_v1beta1_RouterParam(*in, *out, s); err != nil { + return err + } + } else { + out.Router = nil + } + // WARNING: in.Network requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.NetworkFilter vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.NetworkParam) + // WARNING: in.Subnet requires manual conversion: does not exist in peer-type + if err := optional.Convert_int_To_optional_Int(&in.NetworkMTU, &out.NetworkMTU, s); err != nil { + return err + } + // WARNING: in.DNSNameservers requires manual conversion: does not exist in peer-type + if in.ExternalRouterIPs != nil { + in, out := &in.ExternalRouterIPs, &out.ExternalRouterIPs + *out = make([]v1beta1.ExternalRouterIPParam, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_ExternalRouterIPParam_To_v1beta1_ExternalRouterIPParam(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.ExternalRouterIPs = nil + } + // WARNING: in.ExternalNetworkID requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerLoadBalancer requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.APIServerLoadBalancer vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.APIServerLoadBalancer) + if err := optional.Convert_bool_To_optional_Bool(&in.DisableAPIServerFloatingIP, &out.DisableAPIServerFloatingIP, s); err != nil { + return err + } + if err := optional.Convert_string_To_optional_String(&in.APIServerFloatingIP, &out.APIServerFloatingIP, s); err != nil { + return err + } + if err := optional.Convert_string_To_optional_String(&in.APIServerFixedIP, &out.APIServerFixedIP, s); err != nil { + return err + } + if err := optional.Convert_int_To_optional_Int(&in.APIServerPort, &out.APIServerPort, s); err != nil { + return err + } + // WARNING: in.ManagedSecurityGroups requires manual conversion: inconvertible types (bool vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ManagedSecurityGroups) + // WARNING: in.AllowAllInClusterTraffic requires manual conversion: does not exist in peer-type + if err := optional.Convert_bool_To_optional_Bool(&in.DisablePortSecurity, &out.DisablePortSecurity, s); err != nil { + return err + } + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.ControlPlaneEndpoint requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api/api/v1beta1.APIEndpoint vs *sigs.k8s.io/cluster-api/api/v1beta1.APIEndpoint) + out.ControlPlaneAvailabilityZones = *(*[]string)(unsafe.Pointer(&in.ControlPlaneAvailabilityZones)) + if err := optional.Convert_bool_To_optional_Bool(&in.ControlPlaneOmitAvailabilityZone, &out.ControlPlaneOmitAvailabilityZone, s); err != nil { + return err + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(v1beta1.Bastion) + if err := Convert_v1alpha7_Bastion_To_v1beta1_Bastion(*in, *out, s); err != nil { + return err + } + } else { + out.Bastion = nil + } + // WARNING: in.IdentityRef requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.OpenStackIdentityReference vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.OpenStackIdentityReference) + return nil +} + +func autoConvert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(in *v1beta1.OpenStackClusterSpec, out *OpenStackClusterSpec, s conversion.Scope) error { + // WARNING: in.ManagedSubnets requires manual conversion: does not exist in peer-type + if in.Router != nil { + in, out := &in.Router, &out.Router + *out = new(RouterFilter) + if err := Convert_v1beta1_RouterParam_To_v1alpha7_RouterFilter(*in, *out, s); err != nil { + return err + } + } else { + out.Router = nil + } + // WARNING: in.Network requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.NetworkParam vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.NetworkFilter) + // WARNING: in.Subnets requires manual conversion: does not exist in peer-type + if err := optional.Convert_optional_Int_To_int(&in.NetworkMTU, &out.NetworkMTU, s); err != nil { + return err + } + if in.ExternalRouterIPs != nil { + in, out := &in.ExternalRouterIPs, &out.ExternalRouterIPs + *out = make([]ExternalRouterIPParam, len(*in)) + for i := range *in { + if err := Convert_v1beta1_ExternalRouterIPParam_To_v1alpha7_ExternalRouterIPParam(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.ExternalRouterIPs = nil + } + // WARNING: in.ExternalNetwork requires manual conversion: does not exist in peer-type + // WARNING: in.DisableExternalNetwork requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerLoadBalancer requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.APIServerLoadBalancer vs sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.APIServerLoadBalancer) + if err := optional.Convert_optional_Bool_To_bool(&in.DisableAPIServerFloatingIP, &out.DisableAPIServerFloatingIP, s); err != nil { + return err + } + if err := optional.Convert_optional_String_To_string(&in.APIServerFloatingIP, &out.APIServerFloatingIP, s); err != nil { + return err + } + if err := optional.Convert_optional_String_To_string(&in.APIServerFixedIP, &out.APIServerFixedIP, s); err != nil { + return err + } + if err := optional.Convert_optional_Int_To_int(&in.APIServerPort, &out.APIServerPort, s); err != nil { + return err + } + // WARNING: in.ManagedSecurityGroups requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ManagedSecurityGroups vs bool) + if err := optional.Convert_optional_Bool_To_bool(&in.DisablePortSecurity, &out.DisablePortSecurity, s); err != nil { + return err + } + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.ControlPlaneEndpoint requires manual conversion: inconvertible types (*sigs.k8s.io/cluster-api/api/v1beta1.APIEndpoint vs sigs.k8s.io/cluster-api/api/v1beta1.APIEndpoint) + out.ControlPlaneAvailabilityZones = *(*[]string)(unsafe.Pointer(&in.ControlPlaneAvailabilityZones)) + if err := optional.Convert_optional_Bool_To_bool(&in.ControlPlaneOmitAvailabilityZone, &out.ControlPlaneOmitAvailabilityZone, s); err != nil { + return err + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(Bastion) + if err := Convert_v1beta1_Bastion_To_v1alpha7_Bastion(*in, *out, s); err != nil { + return err + } + } else { + out.Bastion = nil + } + // WARNING: in.IdentityRef requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.OpenStackIdentityReference vs *sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7.OpenStackIdentityReference) + return nil +} + +func autoConvert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus(in *OpenStackClusterStatus, out *v1beta1.OpenStackClusterStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.Network = (*v1beta1.NetworkStatusWithSubnets)(unsafe.Pointer(in.Network)) + out.ExternalNetwork = (*v1beta1.NetworkStatus)(unsafe.Pointer(in.ExternalNetwork)) + out.Router = (*v1beta1.Router)(unsafe.Pointer(in.Router)) + if in.APIServerLoadBalancer != nil { + in, out := &in.APIServerLoadBalancer, &out.APIServerLoadBalancer + *out = new(v1beta1.LoadBalancer) + if err := Convert_v1alpha7_LoadBalancer_To_v1beta1_LoadBalancer(*in, *out, s); err != nil { + return err + } + } else { + out.APIServerLoadBalancer = nil + } + out.FailureDomains = *(*apiv1beta1.FailureDomains)(unsafe.Pointer(&in.FailureDomains)) + if in.ControlPlaneSecurityGroup != nil { + in, out := &in.ControlPlaneSecurityGroup, &out.ControlPlaneSecurityGroup + *out = new(v1beta1.SecurityGroupStatus) + if err := Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(*in, *out, s); err != nil { + return err + } + } else { + out.ControlPlaneSecurityGroup = nil + } + if in.WorkerSecurityGroup != nil { + in, out := &in.WorkerSecurityGroup, &out.WorkerSecurityGroup + *out = new(v1beta1.SecurityGroupStatus) + if err := Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(*in, *out, s); err != nil { + return err + } + } else { + out.WorkerSecurityGroup = nil + } + if in.BastionSecurityGroup != nil { + in, out := &in.BastionSecurityGroup, &out.BastionSecurityGroup + *out = new(v1beta1.SecurityGroupStatus) + if err := Convert_v1alpha7_SecurityGroup_To_v1beta1_SecurityGroupStatus(*in, *out, s); err != nil { + return err + } + } else { + out.BastionSecurityGroup = nil + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(v1beta1.BastionStatus) + if err := Convert_v1alpha7_BastionStatus_To_v1beta1_BastionStatus(*in, *out, s); err != nil { + return err + } + } else { + out.Bastion = nil + } + out.FailureReason = (*errors.ClusterStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + return nil +} + +// Convert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus(in *OpenStackClusterStatus, out *v1beta1.OpenStackClusterStatus, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterStatus_To_v1beta1_OpenStackClusterStatus(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(in *v1beta1.OpenStackClusterStatus, out *OpenStackClusterStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.Network = (*NetworkStatusWithSubnets)(unsafe.Pointer(in.Network)) + out.ExternalNetwork = (*NetworkStatus)(unsafe.Pointer(in.ExternalNetwork)) + out.Router = (*Router)(unsafe.Pointer(in.Router)) + if in.APIServerLoadBalancer != nil { + in, out := &in.APIServerLoadBalancer, &out.APIServerLoadBalancer + *out = new(LoadBalancer) + if err := Convert_v1beta1_LoadBalancer_To_v1alpha7_LoadBalancer(*in, *out, s); err != nil { + return err + } + } else { + out.APIServerLoadBalancer = nil + } + out.FailureDomains = *(*apiv1beta1.FailureDomains)(unsafe.Pointer(&in.FailureDomains)) + if in.ControlPlaneSecurityGroup != nil { + in, out := &in.ControlPlaneSecurityGroup, &out.ControlPlaneSecurityGroup + *out = new(SecurityGroup) + if err := Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(*in, *out, s); err != nil { + return err + } + } else { + out.ControlPlaneSecurityGroup = nil + } + if in.WorkerSecurityGroup != nil { + in, out := &in.WorkerSecurityGroup, &out.WorkerSecurityGroup + *out = new(SecurityGroup) + if err := Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(*in, *out, s); err != nil { + return err + } + } else { + out.WorkerSecurityGroup = nil + } + if in.BastionSecurityGroup != nil { + in, out := &in.BastionSecurityGroup, &out.BastionSecurityGroup + *out = new(SecurityGroup) + if err := Convert_v1beta1_SecurityGroupStatus_To_v1alpha7_SecurityGroup(*in, *out, s); err != nil { + return err + } + } else { + out.BastionSecurityGroup = nil + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(BastionStatus) + if err := Convert_v1beta1_BastionStatus_To_v1alpha7_BastionStatus(*in, *out, s); err != nil { + return err + } + } else { + out.Bastion = nil + } + out.FailureReason = (*errors.ClusterStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + return nil +} + +func autoConvert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate(in *OpenStackClusterTemplate, out *v1beta1.OpenStackClusterTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate(in *OpenStackClusterTemplate, out *v1beta1.OpenStackClusterTemplate, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate(in *v1beta1.OpenStackClusterTemplate, out *OpenStackClusterTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate is an autogenerated conversion function. +func Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate(in *v1beta1.OpenStackClusterTemplate, out *OpenStackClusterTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList(in *OpenStackClusterTemplateList, out *v1beta1.OpenStackClusterTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.OpenStackClusterTemplate, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_OpenStackClusterTemplate_To_v1beta1_OpenStackClusterTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList(in *OpenStackClusterTemplateList, out *v1beta1.OpenStackClusterTemplateList, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterTemplateList_To_v1beta1_OpenStackClusterTemplateList(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList(in *v1beta1.OpenStackClusterTemplateList, out *OpenStackClusterTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackClusterTemplate, len(*in)) + for i := range *in { + if err := Convert_v1beta1_OpenStackClusterTemplate_To_v1alpha7_OpenStackClusterTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList is an autogenerated conversion function. +func Convert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList(in *v1beta1.OpenStackClusterTemplateList, out *OpenStackClusterTemplateList, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterTemplateList_To_v1alpha7_OpenStackClusterTemplateList(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource(in *OpenStackClusterTemplateResource, out *v1beta1.OpenStackClusterTemplateResource, s conversion.Scope) error { + if err := Convert_v1alpha7_OpenStackClusterSpec_To_v1beta1_OpenStackClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource(in *OpenStackClusterTemplateResource, out *v1beta1.OpenStackClusterTemplateResource, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource(in *v1beta1.OpenStackClusterTemplateResource, out *OpenStackClusterTemplateResource, s conversion.Scope) error { + if err := Convert_v1beta1_OpenStackClusterSpec_To_v1alpha7_OpenStackClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource is an autogenerated conversion function. +func Convert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource(in *v1beta1.OpenStackClusterTemplateResource, out *OpenStackClusterTemplateResource, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec(in *OpenStackClusterTemplateSpec, out *v1beta1.OpenStackClusterTemplateSpec, s conversion.Scope) error { + if err := Convert_v1alpha7_OpenStackClusterTemplateResource_To_v1beta1_OpenStackClusterTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec(in *OpenStackClusterTemplateSpec, out *v1beta1.OpenStackClusterTemplateSpec, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackClusterTemplateSpec_To_v1beta1_OpenStackClusterTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec(in *v1beta1.OpenStackClusterTemplateSpec, out *OpenStackClusterTemplateSpec, s conversion.Scope) error { + if err := Convert_v1beta1_OpenStackClusterTemplateResource_To_v1alpha7_OpenStackClusterTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec(in *v1beta1.OpenStackClusterTemplateSpec, out *OpenStackClusterTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackClusterTemplateSpec_To_v1alpha7_OpenStackClusterTemplateSpec(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackIdentityReference_To_v1beta1_OpenStackIdentityReference(in *OpenStackIdentityReference, out *v1beta1.OpenStackIdentityReference, s conversion.Scope) error { + // WARNING: in.Kind requires manual conversion: does not exist in peer-type + out.Name = in.Name + return nil +} + +func autoConvert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityReference(in *v1beta1.OpenStackIdentityReference, out *OpenStackIdentityReference, s conversion.Scope) error { + out.Name = in.Name + // WARNING: in.CloudName requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine(in *OpenStackMachine, out *v1beta1.OpenStackMachine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine(in *v1beta1.OpenStackMachine, out *OpenStackMachine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_OpenStackMachineStatus_To_v1alpha7_OpenStackMachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList(in *OpenStackMachineList, out *v1beta1.OpenStackMachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.OpenStackMachine, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_OpenStackMachine_To_v1beta1_OpenStackMachine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList(in *OpenStackMachineList, out *v1beta1.OpenStackMachineList, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineList_To_v1beta1_OpenStackMachineList(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList(in *v1beta1.OpenStackMachineList, out *OpenStackMachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackMachine, len(*in)) + for i := range *in { + if err := Convert_v1beta1_OpenStackMachine_To_v1alpha7_OpenStackMachine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList is an autogenerated conversion function. +func Convert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList(in *v1beta1.OpenStackMachineList, out *OpenStackMachineList, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackMachineList_To_v1alpha7_OpenStackMachineList(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(in *OpenStackMachineSpec, out *v1beta1.OpenStackMachineSpec, s conversion.Scope) error { + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + // WARNING: in.InstanceID requires manual conversion: does not exist in peer-type + // WARNING: in.CloudName requires manual conversion: does not exist in peer-type + out.Flavor = in.Flavor + // WARNING: in.Image requires manual conversion: inconvertible types (string vs sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam) + // WARNING: in.ImageUUID requires manual conversion: does not exist in peer-type + out.SSHKeyName = in.SSHKeyName + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1beta1.PortOpts, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_PortOpts_To_v1beta1_PortOpts(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + // WARNING: in.FloatingIP requires manual conversion: does not exist in peer-type + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]v1beta1.SecurityGroupParam, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupParam(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.SecurityGroups = nil + } + out.Trunk = in.Trunk + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.ServerMetadata requires manual conversion: inconvertible types (map[string]string vs []sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ServerMetadata) + out.ConfigDrive = (*bool)(unsafe.Pointer(in.ConfigDrive)) + if in.RootVolume != nil { + in, out := &in.RootVolume, &out.RootVolume + *out = new(v1beta1.RootVolume) + if err := Convert_v1alpha7_RootVolume_To_v1beta1_RootVolume(*in, *out, s); err != nil { + return err + } + } else { + out.RootVolume = nil + } + if in.AdditionalBlockDevices != nil { + in, out := &in.AdditionalBlockDevices, &out.AdditionalBlockDevices + *out = make([]v1beta1.AdditionalBlockDevice, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_AdditionalBlockDevice_To_v1beta1_AdditionalBlockDevice(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.AdditionalBlockDevices = nil + } + // WARNING: in.ServerGroupID requires manual conversion: does not exist in peer-type + if in.IdentityRef != nil { + in, out := &in.IdentityRef, &out.IdentityRef + *out = new(v1beta1.OpenStackIdentityReference) + if err := Convert_v1alpha7_OpenStackIdentityReference_To_v1beta1_OpenStackIdentityReference(*in, *out, s); err != nil { + return err + } + } else { + out.IdentityRef = nil + } + return nil +} + +func autoConvert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(in *v1beta1.OpenStackMachineSpec, out *OpenStackMachineSpec, s conversion.Scope) error { + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.Flavor = in.Flavor + // WARNING: in.Image requires manual conversion: inconvertible types (sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ImageParam vs string) + out.SSHKeyName = in.SSHKeyName + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]PortOpts, len(*in)) + for i := range *in { + if err := Convert_v1beta1_PortOpts_To_v1alpha7_PortOpts(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Ports = nil + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]SecurityGroupFilter, len(*in)) + for i := range *in { + if err := Convert_v1beta1_SecurityGroupParam_To_v1alpha7_SecurityGroupFilter(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.SecurityGroups = nil + } + out.Trunk = in.Trunk + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.ServerMetadata requires manual conversion: inconvertible types ([]sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1.ServerMetadata vs map[string]string) + out.ConfigDrive = (*bool)(unsafe.Pointer(in.ConfigDrive)) + if in.RootVolume != nil { + in, out := &in.RootVolume, &out.RootVolume + *out = new(RootVolume) + if err := Convert_v1beta1_RootVolume_To_v1alpha7_RootVolume(*in, *out, s); err != nil { + return err + } + } else { + out.RootVolume = nil + } + if in.AdditionalBlockDevices != nil { + in, out := &in.AdditionalBlockDevices, &out.AdditionalBlockDevices + *out = make([]AdditionalBlockDevice, len(*in)) + for i := range *in { + if err := Convert_v1beta1_AdditionalBlockDevice_To_v1alpha7_AdditionalBlockDevice(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.AdditionalBlockDevices = nil + } + // WARNING: in.ServerGroup requires manual conversion: does not exist in peer-type + if in.IdentityRef != nil { + in, out := &in.IdentityRef, &out.IdentityRef + *out = new(OpenStackIdentityReference) + if err := Convert_v1beta1_OpenStackIdentityReference_To_v1alpha7_OpenStackIdentityReference(*in, *out, s); err != nil { + return err + } + } else { + out.IdentityRef = nil + } + // WARNING: in.FloatingIPPoolRef requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus(in *OpenStackMachineStatus, out *v1beta1.OpenStackMachineStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.Addresses = *(*[]corev1.NodeAddress)(unsafe.Pointer(&in.Addresses)) + out.InstanceState = (*v1beta1.InstanceState)(unsafe.Pointer(in.InstanceState)) + out.FailureReason = (*errors.MachineStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Conditions = *(*apiv1beta1.Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus(in *OpenStackMachineStatus, out *v1beta1.OpenStackMachineStatus, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineStatus_To_v1beta1_OpenStackMachineStatus(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineStatus_To_v1alpha7_OpenStackMachineStatus(in *v1beta1.OpenStackMachineStatus, out *OpenStackMachineStatus, s conversion.Scope) error { + out.Ready = in.Ready + // WARNING: in.InstanceID requires manual conversion: does not exist in peer-type + out.Addresses = *(*[]corev1.NodeAddress)(unsafe.Pointer(&in.Addresses)) + out.InstanceState = (*InstanceState)(unsafe.Pointer(in.InstanceState)) + // WARNING: in.Resolved requires manual conversion: does not exist in peer-type + // WARNING: in.Resources requires manual conversion: does not exist in peer-type + out.FailureReason = (*errors.MachineStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Conditions = *(*apiv1beta1.Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +func autoConvert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate(in *OpenStackMachineTemplate, out *v1beta1.OpenStackMachineTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate(in *OpenStackMachineTemplate, out *v1beta1.OpenStackMachineTemplate, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate(in *v1beta1.OpenStackMachineTemplate, out *OpenStackMachineTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate is an autogenerated conversion function. +func Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate(in *v1beta1.OpenStackMachineTemplate, out *OpenStackMachineTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList(in *OpenStackMachineTemplateList, out *v1beta1.OpenStackMachineTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.OpenStackMachineTemplate, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_OpenStackMachineTemplate_To_v1beta1_OpenStackMachineTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList(in *OpenStackMachineTemplateList, out *v1beta1.OpenStackMachineTemplateList, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineTemplateList_To_v1beta1_OpenStackMachineTemplateList(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList(in *v1beta1.OpenStackMachineTemplateList, out *OpenStackMachineTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackMachineTemplate, len(*in)) + for i := range *in { + if err := Convert_v1beta1_OpenStackMachineTemplate_To_v1alpha7_OpenStackMachineTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList is an autogenerated conversion function. +func Convert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList(in *v1beta1.OpenStackMachineTemplateList, out *OpenStackMachineTemplateList, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackMachineTemplateList_To_v1alpha7_OpenStackMachineTemplateList(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource(in *OpenStackMachineTemplateResource, out *v1beta1.OpenStackMachineTemplateResource, s conversion.Scope) error { + if err := Convert_v1alpha7_OpenStackMachineSpec_To_v1beta1_OpenStackMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource(in *OpenStackMachineTemplateResource, out *v1beta1.OpenStackMachineTemplateResource, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource(in *v1beta1.OpenStackMachineTemplateResource, out *OpenStackMachineTemplateResource, s conversion.Scope) error { + if err := Convert_v1beta1_OpenStackMachineSpec_To_v1alpha7_OpenStackMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource is an autogenerated conversion function. +func Convert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource(in *v1beta1.OpenStackMachineTemplateResource, out *OpenStackMachineTemplateResource, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource(in, out, s) +} + +func autoConvert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec(in *OpenStackMachineTemplateSpec, out *v1beta1.OpenStackMachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1alpha7_OpenStackMachineTemplateResource_To_v1beta1_OpenStackMachineTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec is an autogenerated conversion function. +func Convert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec(in *OpenStackMachineTemplateSpec, out *v1beta1.OpenStackMachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1alpha7_OpenStackMachineTemplateSpec_To_v1beta1_OpenStackMachineTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec(in *v1beta1.OpenStackMachineTemplateSpec, out *OpenStackMachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1beta1_OpenStackMachineTemplateResource_To_v1alpha7_OpenStackMachineTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec(in *v1beta1.OpenStackMachineTemplateSpec, out *OpenStackMachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_OpenStackMachineTemplateSpec_To_v1alpha7_OpenStackMachineTemplateSpec(in, out, s) +} + +func autoConvert_v1alpha7_PortOpts_To_v1beta1_PortOpts(in *PortOpts, out *v1beta1.PortOpts, s conversion.Scope) error { + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(v1beta1.NetworkParam) + if err := Convert_v1alpha7_NetworkFilter_To_v1beta1_NetworkParam(*in, *out, s); err != nil { + return err + } + } else { + out.Network = nil + } + if err := optional.Convert_string_To_optional_String(&in.NameSuffix, &out.NameSuffix, s); err != nil { + return err + } + if err := optional.Convert_string_To_optional_String(&in.Description, &out.Description, s); err != nil { + return err + } + // WARNING: in.AdminStateUp requires manual conversion: does not exist in peer-type + // WARNING: in.MACAddress requires manual conversion: does not exist in peer-type + if in.FixedIPs != nil { + in, out := &in.FixedIPs, &out.FixedIPs + *out = make([]v1beta1.FixedIP, len(*in)) + for i := range *in { + if err := Convert_v1alpha7_FixedIP_To_v1beta1_FixedIP(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.FixedIPs = nil + } + // WARNING: in.SecurityGroupFilters requires manual conversion: does not exist in peer-type + // WARNING: in.AllowedAddressPairs requires manual conversion: does not exist in peer-type + out.Trunk = (*bool)(unsafe.Pointer(in.Trunk)) + // WARNING: in.HostID requires manual conversion: does not exist in peer-type + // WARNING: in.VNICType requires manual conversion: does not exist in peer-type + // WARNING: in.Profile requires manual conversion: does not exist in peer-type + // WARNING: in.DisablePortSecurity requires manual conversion: does not exist in peer-type + // WARNING: in.PropagateUplinkStatus requires manual conversion: does not exist in peer-type + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + // WARNING: in.ValueSpecs requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_PortOpts_To_v1alpha7_PortOpts(in *v1beta1.PortOpts, out *PortOpts, s conversion.Scope) error { + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkFilter) + if err := Convert_v1beta1_NetworkParam_To_v1alpha7_NetworkFilter(*in, *out, s); err != nil { + return err + } + } else { + out.Network = nil + } + if err := optional.Convert_optional_String_To_string(&in.Description, &out.Description, s); err != nil { + return err + } + if err := optional.Convert_optional_String_To_string(&in.NameSuffix, &out.NameSuffix, s); err != nil { + return err + } + if in.FixedIPs != nil { + in, out := &in.FixedIPs, &out.FixedIPs + *out = make([]FixedIP, len(*in)) + for i := range *in { + if err := Convert_v1beta1_FixedIP_To_v1alpha7_FixedIP(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.FixedIPs = nil + } + // WARNING: in.SecurityGroups requires manual conversion: does not exist in peer-type + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + out.Trunk = (*bool)(unsafe.Pointer(in.Trunk)) + // WARNING: in.ResolvedPortSpecFields requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_RootVolume_To_v1beta1_RootVolume(in *RootVolume, out *v1beta1.RootVolume, s conversion.Scope) error { + // WARNING: in.Size requires manual conversion: does not exist in peer-type + // WARNING: in.VolumeType requires manual conversion: does not exist in peer-type + // WARNING: in.AvailabilityZone requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_RootVolume_To_v1alpha7_RootVolume(in *v1beta1.RootVolume, out *RootVolume, s conversion.Scope) error { + // WARNING: in.SizeGiB requires manual conversion: does not exist in peer-type + // WARNING: in.BlockDeviceVolume requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_Router_To_v1beta1_Router(in *Router, out *v1beta1.Router, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + out.IPs = *(*[]string)(unsafe.Pointer(&in.IPs)) + return nil +} + +// Convert_v1alpha7_Router_To_v1beta1_Router is an autogenerated conversion function. +func Convert_v1alpha7_Router_To_v1beta1_Router(in *Router, out *v1beta1.Router, s conversion.Scope) error { + return autoConvert_v1alpha7_Router_To_v1beta1_Router(in, out, s) +} + +func autoConvert_v1beta1_Router_To_v1alpha7_Router(in *v1beta1.Router, out *Router, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + out.IPs = *(*[]string)(unsafe.Pointer(&in.IPs)) + return nil +} + +// Convert_v1beta1_Router_To_v1alpha7_Router is an autogenerated conversion function. +func Convert_v1beta1_Router_To_v1alpha7_Router(in *v1beta1.Router, out *Router, s conversion.Scope) error { + return autoConvert_v1beta1_Router_To_v1alpha7_Router(in, out, s) +} + +func autoConvert_v1alpha7_RouterFilter_To_v1beta1_RouterFilter(in *RouterFilter, out *v1beta1.RouterFilter, s conversion.Scope) error { + // WARNING: in.ID requires manual conversion: does not exist in peer-type + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.Tags requires manual conversion: does not exist in peer-type + // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type + // WARNING: in.NotTags requires manual conversion: does not exist in peer-type + // WARNING: in.NotTagsAny requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_RouterFilter_To_v1alpha7_RouterFilter(in *v1beta1.RouterFilter, out *RouterFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_SecurityGroupFilter_To_v1beta1_SecurityGroupFilter(in *SecurityGroupFilter, out *v1beta1.SecurityGroupFilter, s conversion.Scope) error { + // WARNING: in.ID requires manual conversion: does not exist in peer-type + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.Tags requires manual conversion: does not exist in peer-type + // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type + // WARNING: in.NotTags requires manual conversion: does not exist in peer-type + // WARNING: in.NotTagsAny requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_SecurityGroupFilter_To_v1alpha7_SecurityGroupFilter(in *v1beta1.SecurityGroupFilter, out *SecurityGroupFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_Subnet_To_v1beta1_Subnet(in *Subnet, out *v1beta1.Subnet, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.CIDR = in.CIDR + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + return nil +} + +// Convert_v1alpha7_Subnet_To_v1beta1_Subnet is an autogenerated conversion function. +func Convert_v1alpha7_Subnet_To_v1beta1_Subnet(in *Subnet, out *v1beta1.Subnet, s conversion.Scope) error { + return autoConvert_v1alpha7_Subnet_To_v1beta1_Subnet(in, out, s) +} + +func autoConvert_v1beta1_Subnet_To_v1alpha7_Subnet(in *v1beta1.Subnet, out *Subnet, s conversion.Scope) error { + out.Name = in.Name + out.ID = in.ID + out.CIDR = in.CIDR + out.Tags = *(*[]string)(unsafe.Pointer(&in.Tags)) + return nil +} + +// Convert_v1beta1_Subnet_To_v1alpha7_Subnet is an autogenerated conversion function. +func Convert_v1beta1_Subnet_To_v1alpha7_Subnet(in *v1beta1.Subnet, out *Subnet, s conversion.Scope) error { + return autoConvert_v1beta1_Subnet_To_v1alpha7_Subnet(in, out, s) +} + +func autoConvert_v1alpha7_SubnetFilter_To_v1beta1_SubnetFilter(in *SubnetFilter, out *v1beta1.SubnetFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + out.IPVersion = in.IPVersion + out.GatewayIP = in.GatewayIP + out.CIDR = in.CIDR + out.IPv6AddressMode = in.IPv6AddressMode + out.IPv6RAMode = in.IPv6RAMode + // WARNING: in.ID requires manual conversion: does not exist in peer-type + // WARNING: in.Tags requires manual conversion: does not exist in peer-type + // WARNING: in.TagsAny requires manual conversion: does not exist in peer-type + // WARNING: in.NotTags requires manual conversion: does not exist in peer-type + // WARNING: in.NotTagsAny requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_SubnetFilter_To_v1alpha7_SubnetFilter(in *v1beta1.SubnetFilter, out *SubnetFilter, s conversion.Scope) error { + out.Name = in.Name + out.Description = in.Description + out.ProjectID = in.ProjectID + out.IPVersion = in.IPVersion + out.GatewayIP = in.GatewayIP + out.CIDR = in.CIDR + out.IPv6AddressMode = in.IPv6AddressMode + out.IPv6RAMode = in.IPv6RAMode + // WARNING: in.FilterByNeutronTags requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha7_ValueSpec_To_v1beta1_ValueSpec(in *ValueSpec, out *v1beta1.ValueSpec, s conversion.Scope) error { + out.Name = in.Name + out.Key = in.Key + out.Value = in.Value + return nil +} + +// Convert_v1alpha7_ValueSpec_To_v1beta1_ValueSpec is an autogenerated conversion function. +func Convert_v1alpha7_ValueSpec_To_v1beta1_ValueSpec(in *ValueSpec, out *v1beta1.ValueSpec, s conversion.Scope) error { + return autoConvert_v1alpha7_ValueSpec_To_v1beta1_ValueSpec(in, out, s) +} + +func autoConvert_v1beta1_ValueSpec_To_v1alpha7_ValueSpec(in *v1beta1.ValueSpec, out *ValueSpec, s conversion.Scope) error { + out.Name = in.Name + out.Key = in.Key + out.Value = in.Value + return nil +} + +// Convert_v1beta1_ValueSpec_To_v1alpha7_ValueSpec is an autogenerated conversion function. +func Convert_v1beta1_ValueSpec_To_v1alpha7_ValueSpec(in *v1beta1.ValueSpec, out *ValueSpec, s conversion.Scope) error { + return autoConvert_v1beta1_ValueSpec_To_v1alpha7_ValueSpec(in, out, s) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.deepcopy.go index 1d81a834..daa1524d 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.deepcopy.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright 2022 The Kubernetes Authors. +Copyright 2023 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ package v1alpha7 import ( "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" + runtime "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/errors" ) diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conditions_consts.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conditions_consts.go new file mode 100644 index 00000000..cbddf420 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conditions_consts.go @@ -0,0 +1,66 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + +const ( + // InstanceReadyCondition reports on current status of the OpenStack instance. Ready indicates the instance is in a Running state. + InstanceReadyCondition clusterv1.ConditionType = "InstanceReady" + + // WaitingForClusterInfrastructureReason used when machine is waiting for cluster infrastructure to be ready before proceeding. + WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure" + // WaitingForBootstrapDataReason used when machine is waiting for bootstrap data to be ready before proceeding. + WaitingForBootstrapDataReason = "WaitingForBootstrapData" + // InvalidMachineSpecReason used when the machine spec is invalid. + InvalidMachineSpecReason = "InvalidMachineSpec" + // InstanceCreateFailedReason used when creating the instance failed. + InstanceCreateFailedReason = "InstanceCreateFailed" + // InstanceNotFoundReason used when the instance couldn't be retrieved. + InstanceNotFoundReason = "InstanceNotFound" + // InstanceStateErrorReason used when the instance is in error state. + InstanceStateErrorReason = "InstanceStateError" + // InstanceDeletedReason used when the instance is in a deleted state. + InstanceDeletedReason = "InstanceDeleted" + // InstanceNotReadyReason used when the instance is in a pending state. + InstanceNotReadyReason = "InstanceNotReady" + // InstanceDeleteFailedReason used when deleting the instance failed. + InstanceDeleteFailedReason = "InstanceDeleteFailed" + // OpenstackErrorReason used when there is an error communicating with OpenStack. + OpenStackErrorReason = "OpenStackError" +) + +const ( + // APIServerIngressReadyCondition reports on the current status of the network ingress (Loadbalancer, Floating IP) for Control Plane machines. Ready indicates that the instance can receive requests. + APIServerIngressReadyCondition clusterv1.ConditionType = "APIServerIngressReadyCondition" + + // LoadBalancerMemberErrorReason used when the instance could not be added as a loadbalancer member. + LoadBalancerMemberErrorReason = "LoadBalancerMemberError" + // FloatingIPErrorReason used when the floating ip could not be created or attached. + FloatingIPErrorReason = "FloatingIPError" +) + +const ( + // FloatingAddressFromPoolReadyCondition reports on the current status of the Floating IPs from ipam pool. + FloatingAddressFromPoolReadyCondition clusterv1.ConditionType = "FloatingAddressFromPoolReady" + // WaitingForIpamProviderReason used when machine is waiting for ipam provider to be ready before proceeding. + FloatingAddressFromPoolWaitingForIpamProviderReason = "WaitingForIPAMProvider" + // FloatingAddressFromPoolErrorReason is used when there is an error attaching an IP from the pool to an machine. + FloatingAddressFromPoolErrorReason = "FloatingIPError" + // UnableToFindFloatingIPNetworkReason is used when the floating ip network is not found. + UnableToFindFloatingIPNetworkReason = "UnableToFindFloatingIPNetwork" +) diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conversion.go new file mode 100644 index 00000000..d442dc0f --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/conversion.go @@ -0,0 +1,117 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "strings" + + "k8s.io/utils/ptr" +) + +// Hub marks OpenStackCluster as a conversion hub. +func (*OpenStackCluster) Hub() {} + +// Hub marks OpenStackClusterList as a conversion hub. +func (*OpenStackClusterList) Hub() {} + +// Hub marks OpenStackClusterTemplate as a conversion hub. +func (*OpenStackClusterTemplate) Hub() {} + +// Hub marks OpenStackClusterTemplateList as a conversion hub. +func (*OpenStackClusterTemplateList) Hub() {} + +// Hub marks OpenStackMachine as a conversion hub. +func (*OpenStackMachine) Hub() {} + +// Hub marks OpenStackMachineList as a conversion hub. +func (*OpenStackMachineList) Hub() {} + +// Hub marks OpenStackMachineTemplate as a conversion hub. +func (*OpenStackMachineTemplate) Hub() {} + +// Hub marks OpenStackMachineTemplateList as a conversion hub. +func (*OpenStackMachineTemplateList) Hub() {} + +// LegacyCalicoSecurityGroupRules returns a list of security group rules for calico +// that need to be applied to the control plane and worker security groups when +// managed security groups are enabled and upgrading to v1beta1. +func LegacyCalicoSecurityGroupRules() []SecurityGroupRuleSpec { + return []SecurityGroupRuleSpec{ + { + Name: "BGP (calico)", + Description: ptr.To("Created by cluster-api-provider-openstack API conversion - BGP (calico)"), + Direction: "ingress", + EtherType: ptr.To("IPv4"), + PortRangeMin: ptr.To(179), + PortRangeMax: ptr.To(179), + Protocol: ptr.To("tcp"), + RemoteManagedGroups: []ManagedSecurityGroupName{"controlplane", "worker"}, + }, + { + Name: "IP-in-IP (calico)", + Description: ptr.To("Created by cluster-api-provider-openstack API conversion - IP-in-IP (calico)"), + Direction: "ingress", + EtherType: ptr.To("IPv4"), + Protocol: ptr.To("4"), + RemoteManagedGroups: []ManagedSecurityGroupName{"controlplane", "worker"}, + }, + } +} + +// splitTags splits a comma separated list of tags into a slice of tags. +// If the input is an empty string, it returns nil representing no list rather +// than an empty list. +func splitTags(tags string) []NeutronTag { + if tags == "" { + return nil + } + + var ret []NeutronTag + for _, tag := range strings.Split(tags, ",") { + if tag != "" { + ret = append(ret, NeutronTag(tag)) + } + } + + return ret +} + +// JoinTags joins a slice of tags into a comma separated list of tags. +func JoinTags(tags []NeutronTag) string { + var b strings.Builder + for i := range tags { + if i > 0 { + b.WriteString(",") + } + b.WriteString(string(tags[i])) + } + return b.String() +} + +func ConvertAllTagsTo(tags, tagsAny, notTags, notTagsAny string, neutronTags *FilterByNeutronTags) { + neutronTags.Tags = splitTags(tags) + neutronTags.TagsAny = splitTags(tagsAny) + neutronTags.NotTags = splitTags(notTags) + neutronTags.NotTagsAny = splitTags(notTagsAny) +} + +func ConvertAllTagsFrom(neutronTags *FilterByNeutronTags, tags, tagsAny, notTags, notTagsAny *string) { + *tags = JoinTags(neutronTags.Tags) + *tagsAny = JoinTags(neutronTags.TagsAny) + *notTags = JoinTags(neutronTags.NotTags) + *notTagsAny = JoinTags(neutronTags.NotTagsAny) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclusterlist_webhook.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/doc.go similarity index 57% rename from vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclusterlist_webhook.go rename to vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/doc.go index f7749b7a..4bd2e994 100644 --- a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7/openstackclusterlist_webhook.go +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/doc.go @@ -14,19 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha7 - -import ( - "sigs.k8s.io/controller-runtime/pkg/builder" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// log is for logging in this package. -var _ = logf.Log.WithName("openstackclusterlist-resource") - -func (r *OpenStackClusterList) SetupWebhookWithManager(mgr manager.Manager) error { - return builder.WebhookManagedBy(mgr). - For(r). - Complete() -} +// Package v1beta1 contains API Schema definitions for the infrastructure v1beta1 API group. +// +kubebuilder:object:generate=true +// +groupName=infrastructure.cluster.x-k8s.io +package v1beta1 diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/groupversion_info.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/groupversion_info.go new file mode 100644 index 00000000..de2087f7 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/groupversion_info.go @@ -0,0 +1,45 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// package v1beta1 contains API Schema definitions for the infrastructure v1beta1 API group +// +kubebuilder:object:generate=true +// +groupName=infrastructure.cluster.x-k8s.io +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "infrastructure.cluster.x-k8s.io", Version: "v1beta1"} + + // schemeBuilder is used to add go types to the GroupVersionKind scheme. + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = schemeBuilder.AddToScheme + + objectTypes = []runtime.Object{} +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, objectTypes...) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/identity_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/identity_types.go new file mode 100644 index 00000000..d54ed749 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/identity_types.go @@ -0,0 +1,31 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +// OpenStackIdentityReference is a reference to an infrastructure +// provider identity to be used to provision cluster resources. +type OpenStackIdentityReference struct { + // Name is the name of a secret in the same namespace as the resource being provisioned. + // The secret must contain a key named `clouds.yaml` which contains an OpenStack clouds.yaml file. + // The secret may optionally contain a key named `cacert` containing a PEM-encoded CA certificate. + // +kubebuilder:validation:Required + Name string `json:"name"` + + // CloudName specifies the name of the entry in the clouds.yaml file to use. + // +kubebuilder:validation:Required + CloudName string `json:"cloudName"` +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackcluster_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackcluster_types.go new file mode 100644 index 00000000..d6745e5c --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackcluster_types.go @@ -0,0 +1,330 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + capierrors "sigs.k8s.io/cluster-api/errors" + + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" +) + +const ( + // ClusterFinalizer allows ReconcileOpenStackCluster to clean up OpenStack resources associated with OpenStackCluster before + // removing it from the apiserver. + ClusterFinalizer = "openstackcluster.infrastructure.cluster.x-k8s.io" +) + +// OpenStackClusterSpec defines the desired state of OpenStackCluster. +type OpenStackClusterSpec struct { + // ManagedSubnets describe OpenStack Subnets to be created. Cluster actuator will create a network, + // subnets with the defined CIDR, and a router connected to these subnets. Currently only one IPv4 + // subnet is supported. If you leave this empty, no network will be created. + // +kubebuilder:validation:MaxItems=1 + // +listType=atomic + // +optional + ManagedSubnets []SubnetSpec `json:"managedSubnets,omitempty"` + + // Router specifies an existing router to be used if ManagedSubnets are + // specified. If specified, no new router will be created. + // +optional + Router *RouterParam `json:"router,omitempty"` + + // Network specifies an existing network to use if no ManagedSubnets + // are specified. + // +optional + Network *NetworkParam `json:"network,omitempty"` + + // Subnets specifies existing subnets to use if not ManagedSubnets are + // specified. All subnets must be in the network specified by Network. + // There can be zero, one, or two subnets. If no subnets are specified, + // all subnets in Network will be used. If 2 subnets are specified, one + // must be IPv4 and the other IPv6. + // +kubebuilder:validation:MaxItems=2 + // +listType=atomic + // +optional + Subnets []SubnetParam `json:"subnets,omitempty"` + + // NetworkMTU sets the maximum transmission unit (MTU) value to address fragmentation for the private network ID. + // This value will be used only if the Cluster actuator creates the network. + // If left empty, the network will have the default MTU defined in Openstack network service. + // To use this field, the Openstack installation requires the net-mtu neutron API extension. + // +optional + NetworkMTU optional.Int `json:"networkMTU,omitempty"` + + // ExternalRouterIPs is an array of externalIPs on the respective subnets. + // This is necessary if the router needs a fixed ip in a specific subnet. + // +listType=atomic + // +optional + ExternalRouterIPs []ExternalRouterIPParam `json:"externalRouterIPs,omitempty"` + + // ExternalNetwork is the OpenStack Network to be used to get public internet to the VMs. + // This option is ignored if DisableExternalNetwork is set to true. + // + // If ExternalNetwork is defined it must refer to exactly one external network. + // + // If ExternalNetwork is not defined or is empty the controller will use any + // existing external network as long as there is only one. It is an + // error if ExternalNetwork is not defined and there are multiple + // external networks unless DisableExternalNetwork is also set. + // + // If ExternalNetwork is not defined and there are no external networks + // the controller will proceed as though DisableExternalNetwork was set. + // +optional + ExternalNetwork *NetworkParam `json:"externalNetwork,omitempty"` + + // DisableExternalNetwork specifies whether or not to attempt to connect the cluster + // to an external network. This allows for the creation of clusters when connecting + // to an external network is not possible or desirable, e.g. if using a provider network. + // +optional + DisableExternalNetwork optional.Bool `json:"disableExternalNetwork,omitempty"` + + // APIServerLoadBalancer configures the optional LoadBalancer for the APIServer. + // If not specified, no load balancer will be created for the API server. + // +optional + APIServerLoadBalancer *APIServerLoadBalancer `json:"apiServerLoadBalancer,omitempty"` + + // DisableAPIServerFloatingIP determines whether or not to attempt to attach a floating + // IP to the API server. This allows for the creation of clusters when attaching a floating + // IP to the API server (and hence, in many cases, exposing the API server to the internet) + // is not possible or desirable, e.g. if using a shared VLAN for communication between + // management and workload clusters or when the management cluster is inside the + // project network. + // This option requires that the API server use a VIP on the cluster network so that the + // underlying machines can change without changing ControlPlaneEndpoint.Host. + // When using a managed load balancer, this VIP will be managed automatically. + // If not using a managed load balancer, cluster configuration will fail without additional + // configuration to manage the VIP on the control plane machines, which falls outside of + // the scope of this controller. + // +optional + DisableAPIServerFloatingIP optional.Bool `json:"disableAPIServerFloatingIP,omitempty"` + + // APIServerFloatingIP is the floatingIP which will be associated with the API server. + // The floatingIP will be created if it does not already exist. + // If not specified, a new floatingIP is allocated. + // This field is not used if DisableAPIServerFloatingIP is set to true. + // +optional + APIServerFloatingIP optional.String `json:"apiServerFloatingIP,omitempty"` + + // APIServerFixedIP is the fixed IP which will be associated with the API server. + // In the case where the API server has a floating IP but not a managed load balancer, + // this field is not used. + // If a managed load balancer is used and this field is not specified, a fixed IP will + // be dynamically allocated for the load balancer. + // If a managed load balancer is not used AND the API server floating IP is disabled, + // this field MUST be specified and should correspond to a pre-allocated port that + // holds the fixed IP to be used as a VIP. + // +optional + APIServerFixedIP optional.String `json:"apiServerFixedIP,omitempty"` + + // APIServerPort is the port on which the listener on the APIServer + // will be created + // +optional + APIServerPort optional.Int `json:"apiServerPort,omitempty"` + + // ManagedSecurityGroups determines whether OpenStack security groups for the cluster + // will be managed by the OpenStack provider or whether pre-existing security groups will + // be specified as part of the configuration. + // By default, the managed security groups have rules that allow the Kubelet, etcd, and the + // Kubernetes API server to function correctly. + // It's possible to add additional rules to the managed security groups. + // When defined to an empty struct, the managed security groups will be created with the default rules. + // +optional + ManagedSecurityGroups *ManagedSecurityGroups `json:"managedSecurityGroups,omitempty"` + + // DisablePortSecurity disables the port security of the network created for the + // Kubernetes cluster, which also disables SecurityGroups + // +optional + DisablePortSecurity optional.Bool `json:"disablePortSecurity,omitempty"` + + // Tags to set on all resources in cluster which support tags + // +listType=set + // +optional + Tags []string `json:"tags,omitempty"` + + // ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + // It is normally populated automatically by the OpenStackCluster + // controller during cluster provisioning. If it is set on creation the + // control plane endpoint will use the values set here in preference to + // values set elsewhere. + // ControlPlaneEndpoint cannot be modified after ControlPlaneEndpoint.Host has been set. + // +optional + ControlPlaneEndpoint *clusterv1.APIEndpoint `json:"controlPlaneEndpoint,omitempty"` + + // ControlPlaneAvailabilityZones is the set of availability zones which + // control plane machines may be deployed to. + // +listType=set + // +optional + ControlPlaneAvailabilityZones []string `json:"controlPlaneAvailabilityZones,omitempty"` + + // ControlPlaneOmitAvailabilityZone causes availability zone to be + // omitted when creating control plane nodes, allowing the Nova + // scheduler to make a decision on which availability zone to use based + // on other scheduling constraints + // +optional + ControlPlaneOmitAvailabilityZone optional.Bool `json:"controlPlaneOmitAvailabilityZone,omitempty"` + + // Bastion is the OpenStack instance to login the nodes + // + // As a rolling update is not ideal during a bastion host session, we + // prevent changes to a running bastion configuration. To make changes, it's required + // to first set `enabled: false` which will remove the bastion and then changes can be made. + //+optional + Bastion *Bastion `json:"bastion,omitempty"` + + // IdentityRef is a reference to a secret holding OpenStack credentials + // to be used when reconciling this cluster. It is also to reconcile + // machines unless overridden in the machine spec. + // +kubebuilder:validation:Required + IdentityRef OpenStackIdentityReference `json:"identityRef"` +} + +// OpenStackClusterStatus defines the observed state of OpenStackCluster. +type OpenStackClusterStatus struct { + // Ready is true when the cluster infrastructure is ready. + // +kubebuilder:default=false + Ready bool `json:"ready"` + + // Network contains information about the created OpenStack Network. + // +optional + Network *NetworkStatusWithSubnets `json:"network,omitempty"` + + // ExternalNetwork contains information about the external network used for default ingress and egress traffic. + // +optional + ExternalNetwork *NetworkStatus `json:"externalNetwork,omitempty"` + + // Router describes the default cluster router + // +optional + Router *Router `json:"router,omitempty"` + + // APIServerLoadBalancer describes the api server load balancer if one exists + // +optional + APIServerLoadBalancer *LoadBalancer `json:"apiServerLoadBalancer,omitempty"` + + // FailureDomains represent OpenStack availability zones + FailureDomains clusterv1.FailureDomains `json:"failureDomains,omitempty"` + + // ControlPlaneSecurityGroup contains the information about the + // OpenStack Security Group that needs to be applied to control plane + // nodes. + // +optional + ControlPlaneSecurityGroup *SecurityGroupStatus `json:"controlPlaneSecurityGroup,omitempty"` + + // WorkerSecurityGroup contains the information about the OpenStack + // Security Group that needs to be applied to worker nodes. + // +optional + WorkerSecurityGroup *SecurityGroupStatus `json:"workerSecurityGroup,omitempty"` + + // BastionSecurityGroup contains the information about the OpenStack + // Security Group that needs to be applied to worker nodes. + // +optional + BastionSecurityGroup *SecurityGroupStatus `json:"bastionSecurityGroup,omitempty"` + + // Bastion contains the information about the deployed bastion host + // +optional + Bastion *BastionStatus `json:"bastion,omitempty"` + + // FailureReason will be set in the event that there is a terminal problem + // reconciling the OpenStackCluster and will contain a succinct value suitable + // for machine interpretation. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the OpenStackCluster's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of + // OpenStackClusters can be added as events to the OpenStackCluster object + // and/or logged in the controller's output. + // +optional + FailureReason *capierrors.ClusterStatusError `json:"failureReason,omitempty"` + + // FailureMessage will be set in the event that there is a terminal problem + // reconciling the OpenStackCluster and will contain a more verbose string suitable + // for logging and human consumption. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the OpenStackCluster's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of + // OpenStackClusters can be added as events to the OpenStackCluster object + // and/or logged in the controller's output. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=openstackclusters,scope=Namespaced,categories=cluster-api,shortName=osc +// +kubebuilder:storageversion +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this OpenStackCluster belongs" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Cluster infrastructure is ready for OpenStack instances" +// +kubebuilder:printcolumn:name="Network",type="string",JSONPath=".status.network.id",description="Network the cluster is using" +// +kubebuilder:printcolumn:name="Endpoint",type="string",JSONPath=".spec.controlPlaneEndpoint.host",description="API Endpoint",priority=1 +// +kubebuilder:printcolumn:name="Bastion IP",type="string",JSONPath=".status.bastion.floatingIP",description="Bastion address for breakglass access" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of OpenStackCluster" + +// OpenStackCluster is the Schema for the openstackclusters API. +type OpenStackCluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec OpenStackClusterSpec `json:"spec,omitempty"` + Status OpenStackClusterStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// OpenStackClusterList contains a list of OpenStackCluster. +type OpenStackClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []OpenStackCluster `json:"items"` +} + +// ManagedSecurityGroups defines the desired state of security groups and rules for the cluster. +type ManagedSecurityGroups struct { + // allNodesSecurityGroupRules defines the rules that should be applied to all nodes. + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=map + // +listMapKey=name + // +optional + AllNodesSecurityGroupRules []SecurityGroupRuleSpec `json:"allNodesSecurityGroupRules,omitempty" patchStrategy:"merge" patchMergeKey:"name"` + + // AllowAllInClusterTraffic allows all ingress and egress traffic between cluster nodes when set to true. + // +kubebuilder:default=false + // +kubebuilder:validation:Required + AllowAllInClusterTraffic bool `json:"allowAllInClusterTraffic"` +} + +func init() { + objectTypes = append(objectTypes, &OpenStackCluster{}, &OpenStackClusterList{}) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackclustertemplate_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackclustertemplate_types.go new file mode 100644 index 00000000..8516831b --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackclustertemplate_types.go @@ -0,0 +1,58 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OpenStackClusterTemplateResource describes the data needed to create a OpenStackCluster from a template. +type OpenStackClusterTemplateResource struct { + Spec OpenStackClusterSpec `json:"spec"` +} + +// OpenStackClusterTemplateSpec defines the desired state of OpenStackClusterTemplate. +type OpenStackClusterTemplateSpec struct { + Template OpenStackClusterTemplateResource `json:"template"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:resource:path=openstackclustertemplates,scope=Namespaced,categories=cluster-api,shortName=osct + +// OpenStackClusterTemplate is the Schema for the openstackclustertemplates API. +type OpenStackClusterTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec OpenStackClusterTemplateSpec `json:"spec,omitempty"` +} + +//+kubebuilder:object:root=true + +// OpenStackClusterTemplateList contains a list of OpenStackClusterTemplate. +type OpenStackClusterTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []OpenStackClusterTemplate `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &OpenStackClusterTemplate{}, &OpenStackClusterTemplateList{}) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachine_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachine_types.go new file mode 100644 index 00000000..4a6e7984 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachine_types.go @@ -0,0 +1,214 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/errors" + + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" +) + +const ( + // MachineFinalizer allows ReconcileOpenStackMachine to clean up OpenStack resources associated with OpenStackMachine before + // removing it from the apiserver. + MachineFinalizer = "openstackmachine.infrastructure.cluster.x-k8s.io" + IPClaimMachineFinalizer = "openstackmachine.infrastructure.cluster.x-k8s.io/ip-claim" +) + +// OpenStackMachineSpec defines the desired state of OpenStackMachine. +type OpenStackMachineSpec struct { + // ProviderID is the unique identifier as specified by the cloud provider. + ProviderID *string `json:"providerID,omitempty"` + + // The flavor reference for the flavor for your server instance. + Flavor string `json:"flavor"` + + // The image to use for your server instance. + // If the rootVolume is specified, this will be used when creating the root volume. + // +required + Image ImageParam `json:"image"` + + // The ssh key to inject in the instance + SSHKeyName string `json:"sshKeyName,omitempty"` + + // Ports to be attached to the server instance. They are created if a port with the given name does not already exist. + // If not specified a default port will be added for the default cluster network. + Ports []PortOpts `json:"ports,omitempty"` + + // The names of the security groups to assign to the instance + SecurityGroups []SecurityGroupParam `json:"securityGroups,omitempty"` + + // Whether the server instance is created on a trunk port or not. + Trunk bool `json:"trunk,omitempty"` + + // Tags which will be added to the machine and all dependent resources + // which support them. These are in addition to Tags defined on the + // cluster. + // Requires Nova api 2.52 minimum! + // +listType=set + Tags []string `json:"tags,omitempty"` + + // Metadata mapping. Allows you to create a map of key value pairs to add to the server instance. + // +listType=map + // +listMapKey=key + ServerMetadata []ServerMetadata `json:"serverMetadata,omitempty"` + + // Config Drive support + ConfigDrive *bool `json:"configDrive,omitempty"` + + // The volume metadata to boot from + RootVolume *RootVolume `json:"rootVolume,omitempty"` + + // AdditionalBlockDevices is a list of specifications for additional block devices to attach to the server instance + // +listType=map + // +listMapKey=name + // +optional + AdditionalBlockDevices []AdditionalBlockDevice `json:"additionalBlockDevices,omitempty"` + + // The server group to assign the machine to. + // +optional + ServerGroup *ServerGroupParam `json:"serverGroup,omitempty"` + + // IdentityRef is a reference to a secret holding OpenStack credentials + // to be used when reconciling this machine. If not specified, the + // credentials specified in the cluster will be used. + // +optional + IdentityRef *OpenStackIdentityReference `json:"identityRef,omitempty"` + + // floatingIPPoolRef is a reference to a IPPool that will be assigned + // to an IPAddressClaim. Once the IPAddressClaim is fulfilled, the FloatingIP + // will be assigned to the OpenStackMachine. + // +optional + FloatingIPPoolRef *corev1.TypedLocalObjectReference `json:"floatingIPPoolRef,omitempty"` +} + +type ServerMetadata struct { + // Key is the server metadata key + // +kubebuilder:validation:MaxLength:=255 + // +kubebuilder:validation:Required + Key string `json:"key"` + + // Value is the server metadata value + // +kubebuilder:validation:MaxLength:=255 + // +kubebuilder:validation:Required + Value string `json:"value"` +} + +// OpenStackMachineStatus defines the observed state of OpenStackMachine. +type OpenStackMachineStatus struct { + // Ready is true when the provider resource is ready. + // +optional + Ready bool `json:"ready"` + + // InstanceID is the OpenStack instance ID for this machine. + // +optional + InstanceID optional.String `json:"instanceID,omitempty"` + + // Addresses contains the OpenStack instance associated addresses. + Addresses []corev1.NodeAddress `json:"addresses,omitempty"` + + // InstanceState is the state of the OpenStack instance for this machine. + // +optional + InstanceState *InstanceState `json:"instanceState,omitempty"` + + // Resolved contains parts of the machine spec with all external + // references fully resolved. + // +optional + Resolved *ResolvedMachineSpec `json:"resolved,omitempty"` + + // Resources contains references to OpenStack resources created for the machine. + // +optional + Resources *MachineResources `json:"resources,omitempty"` + + FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"` + + // FailureMessage will be set in the event that there is a terminal problem + // reconciling the Machine and will contain a more verbose string suitable + // for logging and human consumption. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the Machine's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the Machine object and/or logged in the + // controller's output. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + Conditions clusterv1.Conditions `json:"conditions,omitempty"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:resource:path=openstackmachines,scope=Namespaced,categories=cluster-api,shortName=osm +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.labels.cluster\\.x-k8s\\.io/cluster-name",description="Cluster to which this OpenStackMachine belongs" +// +kubebuilder:printcolumn:name="InstanceState",type="string",JSONPath=".status.instanceState",description="OpenStack instance state" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.ready",description="Machine ready status" +// +kubebuilder:printcolumn:name="ProviderID",type="string",JSONPath=".spec.providerID",description="OpenStack instance ID" +// +kubebuilder:printcolumn:name="Machine",type="string",JSONPath=".metadata.ownerReferences[?(@.kind==\"Machine\")].name",description="Machine object which owns with this OpenStackMachine" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of OpenStackMachine" + +// OpenStackMachine is the Schema for the openstackmachines API. +type OpenStackMachine struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec OpenStackMachineSpec `json:"spec,omitempty"` + Status OpenStackMachineStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// OpenStackMachineList contains a list of OpenStackMachine. +type OpenStackMachineList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []OpenStackMachine `json:"items"` +} + +// GetConditions returns the observations of the operational state of the OpenStackMachine resource. +func (r *OpenStackMachine) GetConditions() clusterv1.Conditions { + return r.Status.Conditions +} + +// SetConditions sets the underlying service state of the OpenStackMachine to the predescribed clusterv1.Conditions. +func (r *OpenStackMachine) SetConditions(conditions clusterv1.Conditions) { + r.Status.Conditions = conditions +} + +// SetFailure sets the OpenStackMachine status failure reason and failure message. +func (r *OpenStackMachine) SetFailure(failureReason errors.MachineStatusError, failureMessage error) { + r.Status.FailureReason = &failureReason + r.Status.FailureMessage = ptr.To(failureMessage.Error()) +} + +func init() { + objectTypes = append(objectTypes, &OpenStackMachine{}, &OpenStackMachineList{}) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachinetemplate_types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachinetemplate_types.go new file mode 100644 index 00000000..aff1e706 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/openstackmachinetemplate_types.go @@ -0,0 +1,53 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OpenStackMachineTemplateSpec defines the desired state of OpenStackMachineTemplate. +type OpenStackMachineTemplateSpec struct { + Template OpenStackMachineTemplateResource `json:"template"` +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:object:root=true +// +kubebuilder:storageversion +// +kubebuilder:resource:path=openstackmachinetemplates,scope=Namespaced,categories=cluster-api,shortName=osmt + +// OpenStackMachineTemplate is the Schema for the openstackmachinetemplates API. +type OpenStackMachineTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec OpenStackMachineTemplateSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true + +// OpenStackMachineTemplateList contains a list of OpenStackMachineTemplate. +type OpenStackMachineTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []OpenStackMachineTemplate `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &OpenStackMachineTemplate{}, &OpenStackMachineTemplateList{}) +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/types.go new file mode 100644 index 00000000..5bbccb05 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/types.go @@ -0,0 +1,909 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "k8s.io/utils/ptr" + + "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional" +) + +// OpenStackMachineTemplateResource describes the data needed to create a OpenStackMachine from a template. +type OpenStackMachineTemplateResource struct { + // Spec is the specification of the desired behavior of the machine. + Spec OpenStackMachineSpec `json:"spec"` +} + +// ImageParam describes a glance image. It can be specified by ID or filter. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type ImageParam struct { + // ID is the uuid of the image. ID will not be validated before use. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter describes a query for an image. If specified, the combination + // of name and tags must return a single matching image or an error will + // be raised. + // +optional + Filter *ImageFilter `json:"filter,omitempty"` +} + +// ImageFilter describes a query for an image. +// +kubebuilder:validation:MinProperties:=1 +type ImageFilter struct { + // The name of the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised. + // +optional + Name optional.String `json:"name,omitempty"` + + // The tags associated with the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised. + // +listType=set + // +optional + Tags []string `json:"tags,omitempty"` +} + +func (f *ImageFilter) IsZero() bool { + if f == nil { + return true + } + return f.Name == nil && len(f.Tags) == 0 +} + +type ExternalRouterIPParam struct { + // The FixedIP in the corresponding subnet + FixedIP string `json:"fixedIP,omitempty"` + // The subnet in which the FixedIP is used for the Gateway of this router + Subnet SubnetParam `json:"subnet"` +} + +// NeutronTag represents a tag on a Neutron resource. +// It may not be empty and may not contain commas. +// +kubebuilder:validation:Pattern:="^[^,]+$" +// +kubebuilder:validation:MinLength:=1 +type NeutronTag string + +type FilterByNeutronTags struct { + // Tags is a list of tags to filter by. If specified, the resource must + // have all of the tags specified to be included in the result. + // +listType=set + // +optional + Tags []NeutronTag `json:"tags,omitempty"` + + // TagsAny is a list of tags to filter by. If specified, the resource + // must have at least one of the tags specified to be included in the + // result. + // +listType=set + // +optional + TagsAny []NeutronTag `json:"tagsAny,omitempty"` + + // NotTags is a list of tags to filter by. If specified, resources which + // contain all of the given tags will be excluded from the result. + // +listType=set + // +optional + NotTags []NeutronTag `json:"notTags,omitempty"` + + // NotTagsAny is a list of tags to filter by. If specified, resources + // which contain any of the given tags will be excluded from the result. + // +listType=set + // +optional + NotTagsAny []NeutronTag `json:"notTagsAny,omitempty"` +} + +func (f *FilterByNeutronTags) IsZero() bool { + return f == nil || (len(f.Tags) == 0 && len(f.TagsAny) == 0 && len(f.NotTags) == 0 && len(f.NotTagsAny) == 0) +} + +// SecurityGroupParam specifies an OpenStack security group. It may be specified by ID or filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type SecurityGroupParam struct { + // ID is the ID of the security group to use. If ID is provided, the other filters cannot be provided. Must be in UUID format. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter specifies a query to select an OpenStack security group. If provided, cannot be empty. + // +optional + Filter *SecurityGroupFilter `json:"filter,omitempty"` +} + +// SecurityGroupFilter specifies a query to select an OpenStack security group. At least one property must be set. +// +kubebuilder:validation:MinProperties:=1 +type SecurityGroupFilter struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + ProjectID string `json:"projectID,omitempty"` + + FilterByNeutronTags `json:",inline"` +} + +func (f *SecurityGroupFilter) IsZero() bool { + if f == nil { + return true + } + return f.Name == "" && + f.Description == "" && + f.ProjectID == "" && + f.FilterByNeutronTags.IsZero() +} + +// NetworkParam specifies an OpenStack network. It may be specified by either ID or Filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type NetworkParam struct { + // ID is the ID of the network to use. If ID is provided, the other filters cannot be provided. Must be in UUID format. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter specifies a filter to select an OpenStack network. If provided, cannot be empty. + // +optional + Filter *NetworkFilter `json:"filter,omitempty"` +} + +// NetworkFilter specifies a query to select an OpenStack network. At least one property must be set. +// +kubebuilder:validation:MinProperties:=1 +type NetworkFilter struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + ProjectID string `json:"projectID,omitempty"` + + FilterByNeutronTags `json:",inline"` +} + +func (networkFilter *NetworkFilter) IsZero() bool { + if networkFilter == nil { + return true + } + return networkFilter.Name == "" && + networkFilter.Description == "" && + networkFilter.ProjectID == "" && + networkFilter.FilterByNeutronTags.IsZero() +} + +// SubnetParam specifies an OpenStack subnet to use. It may be specified by either ID or filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type SubnetParam struct { + // ID is the uuid of the subnet. It will not be validated. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter specifies a filter to select the subnet. It must match exactly one subnet. + // +optional + Filter *SubnetFilter `json:"filter,omitempty"` +} + +// SubnetFilter specifies a filter to select a subnet. At least one parameter must be specified. +// +kubebuilder:validation:MinProperties:=1 +type SubnetFilter struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + ProjectID string `json:"projectID,omitempty"` + IPVersion int `json:"ipVersion,omitempty"` + GatewayIP string `json:"gatewayIP,omitempty"` + CIDR string `json:"cidr,omitempty"` + IPv6AddressMode string `json:"ipv6AddressMode,omitempty"` + IPv6RAMode string `json:"ipv6RAMode,omitempty"` + + FilterByNeutronTags `json:",inline"` +} + +func (subnetFilter *SubnetFilter) IsZero() bool { + if subnetFilter == nil { + return true + } + return subnetFilter.Name == "" && + subnetFilter.Description == "" && + subnetFilter.ProjectID == "" && + subnetFilter.IPVersion == 0 && + subnetFilter.GatewayIP == "" && + subnetFilter.CIDR == "" && + subnetFilter.IPv6AddressMode == "" && + subnetFilter.IPv6RAMode == "" && + subnetFilter.FilterByNeutronTags.IsZero() +} + +// RouterParam specifies an OpenStack router to use. It may be specified by either ID or filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type RouterParam struct { + // ID is the ID of the router to use. If ID is provided, the other filters cannot be provided. Must be in UUID format. + // +kubebuilder:validation:Format:=uuid + // +optional + ID optional.String `json:"id,omitempty"` + + // Filter specifies a filter to select an OpenStack router. If provided, cannot be empty. + Filter *RouterFilter `json:"filter,omitempty"` +} + +// RouterFilter specifies a query to select an OpenStack router. At least one property must be set. +// +kubebuilder:validation:MinProperties:=1 +type RouterFilter struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + ProjectID string `json:"projectID,omitempty"` + + FilterByNeutronTags `json:",inline"` +} + +func (f *RouterFilter) IsZero() bool { + if f == nil { + return true + } + return f.Name == "" && + f.Description == "" && + f.ProjectID == "" && + f.FilterByNeutronTags.IsZero() +} + +type SubnetSpec struct { + // CIDR is representing the IP address range used to create the subnet, e.g. 10.0.0.0/24. + // This field is required when defining a subnet. + // +required + CIDR string `json:"cidr"` + + // DNSNameservers holds a list of DNS server addresses that will be provided when creating + // the subnet. These addresses need to have the same IP version as CIDR. + DNSNameservers []string `json:"dnsNameservers,omitempty"` + + // AllocationPools is an array of AllocationPool objects that will be applied to OpenStack Subnet being created. + // If set, OpenStack will only allocate these IPs for Machines. It will still be possible to create ports from + // outside of these ranges manually. + AllocationPools []AllocationPool `json:"allocationPools,omitempty"` +} + +type AllocationPool struct { + // Start represents the start of the AllocationPool, that is the lowest IP of the pool. + // +required + Start string `json:"start"` + + // End represents the end of the AlloctionPool, that is the highest IP of the pool. + // +required + End string `json:"end"` +} + +type PortOpts struct { + // Network is a query for an openstack network that the port will be created or discovered on. + // This will fail if the query returns more than one network. + // +optional + Network *NetworkParam `json:"network,omitempty"` + + // Description is a human-readable description for the port. + // +optional + Description optional.String `json:"description,omitempty"` + + // NameSuffix will be appended to the name of the port if specified. If unspecified, instead the 0-based index of the port in the list is used. + // +optional + NameSuffix optional.String `json:"nameSuffix,omitempty"` + + // FixedIPs is a list of pairs of subnet and/or IP address to assign to the port. If specified, these must be subnets of the port's network. + // +optional + // +listType=atomic + FixedIPs []FixedIP `json:"fixedIPs,omitempty"` + + // SecurityGroups is a list of the names, uuids, filters or any combination these of the security groups to assign to the instance. + // +optional + // +listType=atomic + SecurityGroups []SecurityGroupParam `json:"securityGroups,omitempty"` + + // Tags applied to the port (and corresponding trunk, if a trunk is configured.) + // These tags are applied in addition to the instance's tags, which will also be applied to the port. + // +listType=set + // +optional + Tags []string `json:"tags,omitempty"` + + // Trunk specifies whether trunking is enabled at the port level. If not + // provided the value is inherited from the machine, or false for a + // bastion host. + // +optional + Trunk *bool `json:"trunk,omitempty"` + + ResolvedPortSpecFields `json:",inline"` +} + +// ResolvePortSpecFields is a convenience struct containing all fields of a +// PortOpts which don't contain references which need to be resolved, and can +// therefore be shared with ResolvedPortSpec. +type ResolvedPortSpecFields struct { + // AdminStateUp specifies whether the port should be created in the up (true) or down (false) state. The default is up. + // +optional + AdminStateUp *bool `json:"adminStateUp,omitempty"` + + // MACAddress specifies the MAC address of the port. If not specified, the MAC address will be generated. + // +optional + MACAddress optional.String `json:"macAddress,omitempty"` + + // AllowedAddressPairs is a list of address pairs which Neutron will + // allow the port to send traffic from in addition to the port's + // addresses. If not specified, the MAC Address will be the MAC Address + // of the port. Depending on the configuration of Neutron, it may be + // supported to specify a CIDR instead of a specific IP address. + // +optional + AllowedAddressPairs []AddressPair `json:"allowedAddressPairs,omitempty"` + + // HostID specifies the ID of the host where the port resides. + // +optional + HostID optional.String `json:"hostID,omitempty"` + + // VNICType specifies the type of vNIC which this port should be + // attached to. This is used to determine which mechanism driver(s) to + // be used to bind the port. The valid values are normal, macvtap, + // direct, baremetal, direct-physical, virtio-forwarder, smart-nic and + // remote-managed, although these values will not be validated in this + // API to ensure compatibility with future neutron changes or custom + // implementations. What type of vNIC is actually available depends on + // deployments. If not specified, the Neutron default value is used. + // +optional + VNICType optional.String `json:"vnicType,omitempty"` + + // Profile is a set of key-value pairs that are used for binding + // details. We intentionally don't expose this as a map[string]string + // because we only want to enable the users to set the values of the + // keys that are known to work in OpenStack Networking API. See + // https://docs.openstack.org/api-ref/network/v2/index.html?expanded=create-port-detail#create-port + // To set profiles, your tenant needs permissions rule:create_port, and + // rule:create_port:binding:profile + // +optional + Profile *BindingProfile `json:"profile,omitempty"` + + // DisablePortSecurity enables or disables the port security when set. + // When not set, it takes the value of the corresponding field at the network level. + // +optional + DisablePortSecurity *bool `json:"disablePortSecurity,omitempty"` + + // PropageteUplinkStatus enables or disables the propagate uplink status on the port. + // +optional + PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"` + + // Value specs are extra parameters to include in the API request with OpenStack. + // This is an extension point for the API, so what they do and if they are supported, + // depends on the specific OpenStack implementation. + // +optional + // +listType=map + // +listMapKey=name + ValueSpecs []ValueSpec `json:"valueSpecs,omitempty"` +} + +// ResolvedPortSpec is a PortOpts with all contained references fully resolved. +type ResolvedPortSpec struct { + // Name is the name of the port. + Name string `json:"name"` + + // Description is a human-readable description for the port. + Description string `json:"description"` + + // NetworkID is the ID of the network the port will be created in. + NetworkID string `json:"networkID"` + + // Tags applied to the port (and corresponding trunk, if a trunk is configured.) + // +listType=set + // +optional + Tags []string `json:"tags,omitempty"` + + // Trunk specifies whether trunking is enabled at the port level. + // +optional + Trunk optional.Bool `json:"trunk,omitempty"` + + // FixedIPs is a list of pairs of subnet and/or IP address to assign to the port. If specified, these must be subnets of the port's network. + // +optional + // +listType=atomic + FixedIPs []ResolvedFixedIP `json:"fixedIPs,omitempty"` + + // SecurityGroups is a list of security group IDs to assign to the port. + // +optional + // +listType=atomic + SecurityGroups []string `json:"securityGroups,omitempty"` + + ResolvedPortSpecFields `json:",inline"` +} + +type PortStatus struct { + // ID is the unique identifier of the port. + // +required + ID string `json:"id"` +} + +type BindingProfile struct { + // OVSHWOffload enables or disables the OVS hardware offload feature. + // +optional + OVSHWOffload *bool `json:"ovsHWOffload,omitempty"` + + // TrustedVF enables or disables the “trusted mode” for the VF. + // +optional + TrustedVF *bool `json:"trustedVF,omitempty"` +} + +type FixedIP struct { + // Subnet is an openstack subnet query that will return the id of a subnet to create + // the fixed IP of a port in. This query must not return more than one subnet. + // +optional + Subnet *SubnetParam `json:"subnet,omitempty"` + + // IPAddress is a specific IP address to assign to the port. If Subnet + // is also specified, IPAddress must be a valid IP address in the + // subnet. If Subnet is not specified, IPAddress must be a valid IP + // address in any subnet of the port's network. + // +optional + IPAddress optional.String `json:"ipAddress,omitempty"` +} + +// ResolvedFixedIP is a FixedIP with the Subnet resolved to an ID. +type ResolvedFixedIP struct { + // SubnetID is the id of a subnet to create the fixed IP of a port in. + // +optional + SubnetID optional.String `json:"subnet,omitempty"` + + // IPAddress is a specific IP address to assign to the port. If SubnetID + // is also specified, IPAddress must be a valid IP address in the + // subnet. If Subnet is not specified, IPAddress must be a valid IP + // address in any subnet of the port's network. + // +optional + IPAddress optional.String `json:"ipAddress,omitempty"` +} + +type AddressPair struct { + // IPAddress is the IP address of the allowed address pair. Depending on + // the configuration of Neutron, it may be supported to specify a CIDR + // instead of a specific IP address. + // +kubebuilder:validation:Required + IPAddress string `json:"ipAddress"` + + // MACAddress is the MAC address of the allowed address pair. If not + // specified, the MAC address will be the MAC address of the port. + // +optional + MACAddress optional.String `json:"macAddress,omitempty"` +} + +type BastionStatus struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + SSHKeyName string `json:"sshKeyName,omitempty"` + State InstanceState `json:"state,omitempty"` + IP string `json:"ip,omitempty"` + FloatingIP string `json:"floatingIP,omitempty"` + + // Resolved contains parts of the bastion's machine spec with all + // external references fully resolved. + // +optional + Resolved *ResolvedMachineSpec `json:"resolved,omitempty"` + + // Resources contains references to OpenStack resources created for the bastion. + // +optional + Resources *MachineResources `json:"resources,omitempty"` +} + +type RootVolume struct { + // SizeGiB is the size of the block device in gibibytes (GiB). + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum:=1 + SizeGiB int `json:"sizeGiB"` + + BlockDeviceVolume `json:",inline"` +} + +// BlockDeviceStorage is the storage type of a block device to create and +// contains additional storage options. +// +union +// +//nolint:godot +type BlockDeviceStorage struct { + // Type is the type of block device to create. + // This can be either "Volume" or "Local". + // +unionDiscriminator + Type BlockDeviceType `json:"type"` + + // Volume contains additional storage options for a volume block device. + // +optional + // +unionMember,optional + Volume *BlockDeviceVolume `json:"volume,omitempty"` +} + +// BlockDeviceVolume contains additional storage options for a volume block device. +type BlockDeviceVolume struct { + // Type is the Cinder volume type of the volume. + // If omitted, the default Cinder volume type that is configured in the OpenStack cloud + // will be used. + // +optional + Type string `json:"type,omitempty"` + + // AvailabilityZone is the volume availability zone to create the volume + // in. If not specified, the volume will be created without an explicit + // availability zone. + // +optional + AvailabilityZone *VolumeAvailabilityZone `json:"availabilityZone,omitempty"` +} + +// VolumeAZSource specifies where to obtain the availability zone for a volume. +// +kubebuilder:validation:Enum=Name;Machine +type VolumeAZSource string + +const ( + VolumeAZFromName VolumeAZSource = "Name" + VolumeAZFromMachine VolumeAZSource = "Machine" +) + +// VolumeAZName is the name of a volume availability zone. It may not contain spaces. +// +kubebuilder:validation:Pattern:="^[^ ]+$" +// +kubebuilder:validation:MinLength:=1 +type VolumeAZName string + +// VolumeAvailabilityZone specifies the availability zone for a volume. +// +kubebuilder:validation:XValidation:rule="!has(self.from) || self.from == 'Name' ? has(self.name) : !has(self.name)",message="name is required when from is 'Name' or default" +type VolumeAvailabilityZone struct { + // From specifies where we will obtain the availability zone for the + // volume. The options are "Name" and "Machine". If "Name" is specified + // then the Name field must also be specified. If "Machine" is specified + // the volume will use the value of FailureDomain, if any, from the + // associated Machine. + // +kubebuilder:default:=Name + // +optional + From VolumeAZSource `json:"from,omitempty"` + + // Name is the name of a volume availability zone to use. It is required + // if From is "Name". The volume availability zone name may not contain + // spaces. + // +optional + Name *VolumeAZName `json:"name,omitempty"` +} + +// AdditionalBlockDevice is a block device to attach to the server. +type AdditionalBlockDevice struct { + // Name of the block device in the context of a machine. + // If the block device is a volume, the Cinder volume will be named + // as a combination of the machine name and this name. + // Also, this name will be used for tagging the block device. + // Information about the block device tag can be obtained from the OpenStack + // metadata API or the config drive. + // Name cannot be 'root', which is reserved for the root volume. + // +kubebuilder:validation:Required + Name string `json:"name"` + + // SizeGiB is the size of the block device in gibibytes (GiB). + // +kubebuilder:validation:Required + // +kubebuilder:validation:Minimum:=1 + SizeGiB int `json:"sizeGiB"` + + // Storage specifies the storage type of the block device and + // additional storage options. + Storage BlockDeviceStorage `json:"storage"` +} + +// ServerGroupParam specifies an OpenStack server group. It may be specified by ID or filter, but not both. +// +kubebuilder:validation:MaxProperties:=1 +// +kubebuilder:validation:MinProperties:=1 +type ServerGroupParam struct { + // ID is the ID of the server group to use. + // +kubebuilder:validation:Format:=uuid + ID optional.String `json:"id,omitempty"` + + // Filter specifies a query to select an OpenStack server group. If provided, it cannot be empty. + Filter *ServerGroupFilter `json:"filter,omitempty"` +} + +// ServerGroupFilter specifies a query to select an OpenStack server group. At least one property must be set. +// +kubebuilder:validation:MinProperties:=1 +type ServerGroupFilter struct { + // Name is the name of a server group to look for. + Name optional.String `json:"name,omitempty"` +} + +func (f *ServerGroupFilter) IsZero() bool { + if f == nil { + return true + } + return f.Name == nil +} + +// BlockDeviceType defines the type of block device to create. +type BlockDeviceType string + +const ( + // LocalBlockDevice is an ephemeral block device attached to the server. + LocalBlockDevice BlockDeviceType = "Local" + + // VolumeBlockDevice is a volume block device attached to the server. + VolumeBlockDevice BlockDeviceType = "Volume" +) + +// NetworkStatus contains basic information about an existing neutron network. +type NetworkStatus struct { + Name string `json:"name"` + ID string `json:"id"` + + //+optional + Tags []string `json:"tags,omitempty"` +} + +// NetworkStatusWithSubnets represents basic information about an existing neutron network and an associated set of subnets. +type NetworkStatusWithSubnets struct { + NetworkStatus `json:",inline"` + + // Subnets is a list of subnets associated with the default cluster network. Machines which use the default cluster network will get an address from all of these subnets. + Subnets []Subnet `json:"subnets,omitempty"` +} + +// Subnet represents basic information about the associated OpenStack Neutron Subnet. +type Subnet struct { + Name string `json:"name"` + ID string `json:"id"` + + CIDR string `json:"cidr"` + + //+optional + Tags []string `json:"tags,omitempty"` +} + +// Router represents basic information about the associated OpenStack Neutron Router. +type Router struct { + Name string `json:"name"` + ID string `json:"id"` + //+optional + Tags []string `json:"tags,omitempty"` + //+optional + IPs []string `json:"ips,omitempty"` +} + +// LoadBalancer represents basic information about the associated OpenStack LoadBalancer. +type LoadBalancer struct { + Name string `json:"name"` + ID string `json:"id"` + IP string `json:"ip"` + InternalIP string `json:"internalIP"` + //+optional + AllowedCIDRs []string `json:"allowedCIDRs,omitempty"` + //+optional + Tags []string `json:"tags,omitempty"` + // LoadBalancerNetwork contains information about network and/or subnets which the + // loadbalancer is allocated on. + // If subnets are specified within the LoadBalancerNetwork currently only the first + // subnet in the list is taken into account. + // +optional + LoadBalancerNetwork *NetworkStatusWithSubnets `json:"loadBalancerNetwork,omitempty"` +} + +// SecurityGroupStatus represents the basic information of the associated +// OpenStack Neutron Security Group. +type SecurityGroupStatus struct { + // name of the security group + // +kubebuilder:validation:Required + Name string `json:"name"` + + // id of the security group + // +kubebuilder:validation:Required + ID string `json:"id"` +} + +// SecurityGroupRuleSpec represent the basic information of the associated OpenStack +// Security Group Role. +// For now this is only used for the allNodesSecurityGroupRules but when we add +// other security groups, we'll need to add a validation because +// Remote* fields are mutually exclusive. +type SecurityGroupRuleSpec struct { + // name of the security group rule. + // It's used to identify the rule so it can be patched and will not be sent to the OpenStack API. + // +kubebuilder:validation:Required + Name string `json:"name"` + + // description of the security group rule. + // +optional + Description *string `json:"description,omitempty"` + + // direction in which the security group rule is applied. The only values + // allowed are "ingress" or "egress". For a compute instance, an ingress + // security group rule is applied to incoming (ingress) traffic for that + // instance. An egress rule is applied to traffic leaving the instance. + // +kubebuilder:validation:Required + // +kubebuilder:validation:enum=ingress;egress + Direction string `json:"direction"` + + // etherType must be IPv4 or IPv6, and addresses represented in CIDR must match the + // ingress or egress rules. + // +kubebuilder:validation:enum=IPv4;IPv6 + // +optional + EtherType *string `json:"etherType,omitempty"` + + // portRangeMin is a number in the range that is matched by the security group + // rule. If the protocol is TCP or UDP, this value must be less than or equal + // to the value of the portRangeMax attribute. + // +optional + PortRangeMin *int `json:"portRangeMin,omitempty"` + + // portRangeMax is a number in the range that is matched by the security group + // rule. The portRangeMin attribute constrains the portRangeMax attribute. + // +optional + PortRangeMax *int `json:"portRangeMax,omitempty"` + + // protocol is the protocol that is matched by the security group rule. + // +optional + Protocol *string `json:"protocol,omitempty"` + + // remoteGroupID is the remote group ID to be associated with this security group rule. + // You can specify either remoteGroupID or remoteIPPrefix or remoteManagedGroups. + // +optional + RemoteGroupID *string `json:"remoteGroupID,omitempty"` + + // remoteIPPrefix is the remote IP prefix to be associated with this security group rule. + // You can specify either remoteGroupID or remoteIPPrefix or remoteManagedGroups. + // +optional + RemoteIPPrefix *string `json:"remoteIPPrefix,omitempty"` + + // remoteManagedGroups is the remote managed groups to be associated with this security group rule. + // You can specify either remoteGroupID or remoteIPPrefix or remoteManagedGroups. + // +optional + RemoteManagedGroups []ManagedSecurityGroupName `json:"remoteManagedGroups,omitempty"` +} + +// +kubebuilder:validation:Enum=bastion;controlplane;worker +type ManagedSecurityGroupName string + +func (m ManagedSecurityGroupName) String() string { + return string(m) +} + +// InstanceState describes the state of an OpenStack instance. +type InstanceState string + +var ( + // InstanceStateBuild is the string representing an instance in a build state. + InstanceStateBuild = InstanceState("BUILD") + + // InstanceStateActive is the string representing an instance in an active state. + InstanceStateActive = InstanceState("ACTIVE") + + // InstanceStateError is the string representing an instance in an error state. + InstanceStateError = InstanceState("ERROR") + + // InstanceStateStopped is the string representing an instance in a stopped state. + InstanceStateStopped = InstanceState("STOPPED") + + // InstanceStateShutoff is the string representing an instance in a shutoff state. + InstanceStateShutoff = InstanceState("SHUTOFF") + + // InstanceStateDeleted is the string representing an instance in a deleted state. + InstanceStateDeleted = InstanceState("DELETED") + + // InstanceStateUndefined is the string representing an undefined instance state. + InstanceStateUndefined = InstanceState("") +) + +// Bastion represents basic information about the bastion node. If you enable bastion, the spec has to be specified. +// +kubebuilder:validation:XValidation:rule="!self.enabled || has(self.spec)",message="spec is required if bastion is enabled" +type Bastion struct { + // Enabled means that bastion is enabled. The bastion is enabled by + // default if this field is not specified. Set this field to false to disable the + // bastion. + // + // It is not currently possible to remove the bastion from the cluster + // spec without first disabling it by setting this field to false and + // waiting until the bastion has been deleted. + // +kubebuilder:default:=true + // +optional + Enabled *bool `json:"enabled,omitempty"` + + // Spec for the bastion itself + Spec *OpenStackMachineSpec `json:"spec,omitempty"` + + // AvailabilityZone is the failure domain that will be used to create the Bastion Spec. + //+optional + AvailabilityZone optional.String `json:"availabilityZone,omitempty"` + + // FloatingIP which will be associated to the bastion machine. It's the IP address, not UUID. + // The floating IP should already exist and should not be associated with a port. If FIP of this address does not + // exist, CAPO will try to create it, but by default only OpenStack administrators have privileges to do so. + //+optional + //+kubebuilder:validation:Format:=ipv4 + FloatingIP optional.String `json:"floatingIP,omitempty"` +} + +func (b *Bastion) IsEnabled() bool { + if b == nil { + return false + } + return b.Enabled == nil || *b.Enabled +} + +type APIServerLoadBalancer struct { + // Enabled defines whether a load balancer should be created. This value + // defaults to true if an APIServerLoadBalancer is given. + // + // There is no reason to set this to false. To disable creation of the + // API server loadbalancer, omit the APIServerLoadBalancer field in the + // cluster spec instead. + // + // +kubebuilder:validation:Required + // +kubebuilder:default:=true + Enabled *bool `json:"enabled"` + + // AdditionalPorts adds additional tcp ports to the load balancer. + // +optional + // +listType=set + AdditionalPorts []int `json:"additionalPorts,omitempty"` + + // AllowedCIDRs restrict access to all API-Server listeners to the given address CIDRs. + // +optional + // +listType=set + AllowedCIDRs []string `json:"allowedCIDRs,omitempty"` + + // Provider specifies name of a specific Octavia provider to use for the + // API load balancer. The Octavia default will be used if it is not + // specified. + // +optional + Provider optional.String `json:"provider,omitempty"` + + // Network defines which network should the load balancer be allocated on. + //+optional + Network *NetworkParam `json:"network,omitempty"` + + // Subnets define which subnets should the load balancer be allocated on. + // It is expected that subnets are located on the network specified in this resource. + // Only the first element is taken into account. + // +optional + // +listType=atomic + // kubebuilder:validation:MaxLength:=2 + Subnets []SubnetParam `json:"subnets,omitempty"` + + // AvailabilityZone is the failure domain that will be used to create the APIServerLoadBalancer Spec. + //+optional + AvailabilityZone optional.String `json:"availabilityZone,omitempty"` +} + +func (s *APIServerLoadBalancer) IsZero() bool { + return s == nil || ((s.Enabled == nil || !*s.Enabled) && len(s.AdditionalPorts) == 0 && len(s.AllowedCIDRs) == 0 && ptr.Deref(s.Provider, "") == "") +} + +func (s *APIServerLoadBalancer) IsEnabled() bool { + // The CRD default value for Enabled is true, so if the field is nil, it should be considered as true. + return s != nil && (s.Enabled == nil || *s.Enabled) +} + +// ResolvedMachineSpec contains resolved references to resources required by the machine. +type ResolvedMachineSpec struct { + // ServerGroupID is the ID of the server group the machine should be added to and is calculated based on ServerGroupFilter. + // +optional + ServerGroupID string `json:"serverGroupID,omitempty"` + + // ImageID is the ID of the image to use for the machine and is calculated based on ImageFilter. + // +optional + ImageID string `json:"imageID,omitempty"` + + // Ports is the fully resolved list of ports to create for the machine. + // +optional + Ports []ResolvedPortSpec `json:"ports,omitempty"` +} + +type MachineResources struct { + // Ports is the status of the ports created for the machine. + // +optional + Ports []PortStatus `json:"ports,omitempty"` +} + +// ValueSpec represents a single value_spec key-value pair. +type ValueSpec struct { + // Name is the name of the key-value pair. + // This is just for identifying the pair and will not be sent to the OpenStack API. + // +kubebuilder:validation:Required + Name string `json:"name"` + // Key is the key in the key-value pair. + // +kubebuilder:validation:Required + Key string `json:"key"` + // Value is the value in the key-value pair. + // +kubebuilder:validation:Required + Value string `json:"value"` +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000..e0e7e28a --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,1770 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/errors" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServerLoadBalancer) DeepCopyInto(out *APIServerLoadBalancer) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.AdditionalPorts != nil { + in, out := &in.AdditionalPorts, &out.AdditionalPorts + *out = make([]int, len(*in)) + copy(*out, *in) + } + if in.AllowedCIDRs != nil { + in, out := &in.AllowedCIDRs, &out.AllowedCIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Provider != nil { + in, out := &in.Provider, &out.Provider + *out = new(string) + **out = **in + } + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkParam) + (*in).DeepCopyInto(*out) + } + if in.Subnets != nil { + in, out := &in.Subnets, &out.Subnets + *out = make([]SubnetParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AvailabilityZone != nil { + in, out := &in.AvailabilityZone, &out.AvailabilityZone + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServerLoadBalancer. +func (in *APIServerLoadBalancer) DeepCopy() *APIServerLoadBalancer { + if in == nil { + return nil + } + out := new(APIServerLoadBalancer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdditionalBlockDevice) DeepCopyInto(out *AdditionalBlockDevice) { + *out = *in + in.Storage.DeepCopyInto(&out.Storage) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdditionalBlockDevice. +func (in *AdditionalBlockDevice) DeepCopy() *AdditionalBlockDevice { + if in == nil { + return nil + } + out := new(AdditionalBlockDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddressPair) DeepCopyInto(out *AddressPair) { + *out = *in + if in.MACAddress != nil { + in, out := &in.MACAddress, &out.MACAddress + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPair. +func (in *AddressPair) DeepCopy() *AddressPair { + if in == nil { + return nil + } + out := new(AddressPair) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AllocationPool) DeepCopyInto(out *AllocationPool) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllocationPool. +func (in *AllocationPool) DeepCopy() *AllocationPool { + if in == nil { + return nil + } + out := new(AllocationPool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Bastion) DeepCopyInto(out *Bastion) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Spec != nil { + in, out := &in.Spec, &out.Spec + *out = new(OpenStackMachineSpec) + (*in).DeepCopyInto(*out) + } + if in.AvailabilityZone != nil { + in, out := &in.AvailabilityZone, &out.AvailabilityZone + *out = new(string) + **out = **in + } + if in.FloatingIP != nil { + in, out := &in.FloatingIP, &out.FloatingIP + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bastion. +func (in *Bastion) DeepCopy() *Bastion { + if in == nil { + return nil + } + out := new(Bastion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BastionStatus) DeepCopyInto(out *BastionStatus) { + *out = *in + if in.Resolved != nil { + in, out := &in.Resolved, &out.Resolved + *out = new(ResolvedMachineSpec) + (*in).DeepCopyInto(*out) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(MachineResources) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BastionStatus. +func (in *BastionStatus) DeepCopy() *BastionStatus { + if in == nil { + return nil + } + out := new(BastionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BindingProfile) DeepCopyInto(out *BindingProfile) { + *out = *in + if in.OVSHWOffload != nil { + in, out := &in.OVSHWOffload, &out.OVSHWOffload + *out = new(bool) + **out = **in + } + if in.TrustedVF != nil { + in, out := &in.TrustedVF, &out.TrustedVF + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BindingProfile. +func (in *BindingProfile) DeepCopy() *BindingProfile { + if in == nil { + return nil + } + out := new(BindingProfile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BlockDeviceStorage) DeepCopyInto(out *BlockDeviceStorage) { + *out = *in + if in.Volume != nil { + in, out := &in.Volume, &out.Volume + *out = new(BlockDeviceVolume) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlockDeviceStorage. +func (in *BlockDeviceStorage) DeepCopy() *BlockDeviceStorage { + if in == nil { + return nil + } + out := new(BlockDeviceStorage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BlockDeviceVolume) DeepCopyInto(out *BlockDeviceVolume) { + *out = *in + if in.AvailabilityZone != nil { + in, out := &in.AvailabilityZone, &out.AvailabilityZone + *out = new(VolumeAvailabilityZone) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BlockDeviceVolume. +func (in *BlockDeviceVolume) DeepCopy() *BlockDeviceVolume { + if in == nil { + return nil + } + out := new(BlockDeviceVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalRouterIPParam) DeepCopyInto(out *ExternalRouterIPParam) { + *out = *in + in.Subnet.DeepCopyInto(&out.Subnet) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalRouterIPParam. +func (in *ExternalRouterIPParam) DeepCopy() *ExternalRouterIPParam { + if in == nil { + return nil + } + out := new(ExternalRouterIPParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FilterByNeutronTags) DeepCopyInto(out *FilterByNeutronTags) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]NeutronTag, len(*in)) + copy(*out, *in) + } + if in.TagsAny != nil { + in, out := &in.TagsAny, &out.TagsAny + *out = make([]NeutronTag, len(*in)) + copy(*out, *in) + } + if in.NotTags != nil { + in, out := &in.NotTags, &out.NotTags + *out = make([]NeutronTag, len(*in)) + copy(*out, *in) + } + if in.NotTagsAny != nil { + in, out := &in.NotTagsAny, &out.NotTagsAny + *out = make([]NeutronTag, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FilterByNeutronTags. +func (in *FilterByNeutronTags) DeepCopy() *FilterByNeutronTags { + if in == nil { + return nil + } + out := new(FilterByNeutronTags) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FixedIP) DeepCopyInto(out *FixedIP) { + *out = *in + if in.Subnet != nil { + in, out := &in.Subnet, &out.Subnet + *out = new(SubnetParam) + (*in).DeepCopyInto(*out) + } + if in.IPAddress != nil { + in, out := &in.IPAddress, &out.IPAddress + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FixedIP. +func (in *FixedIP) DeepCopy() *FixedIP { + if in == nil { + return nil + } + out := new(FixedIP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageFilter) DeepCopyInto(out *ImageFilter) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageFilter. +func (in *ImageFilter) DeepCopy() *ImageFilter { + if in == nil { + return nil + } + out := new(ImageFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageParam) DeepCopyInto(out *ImageParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(ImageFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageParam. +func (in *ImageParam) DeepCopy() *ImageParam { + if in == nil { + return nil + } + out := new(ImageParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) { + *out = *in + if in.AllowedCIDRs != nil { + in, out := &in.AllowedCIDRs, &out.AllowedCIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.LoadBalancerNetwork != nil { + in, out := &in.LoadBalancerNetwork, &out.LoadBalancerNetwork + *out = new(NetworkStatusWithSubnets) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer. +func (in *LoadBalancer) DeepCopy() *LoadBalancer { + if in == nil { + return nil + } + out := new(LoadBalancer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineResources) DeepCopyInto(out *MachineResources) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]PortStatus, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineResources. +func (in *MachineResources) DeepCopy() *MachineResources { + if in == nil { + return nil + } + out := new(MachineResources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedSecurityGroups) DeepCopyInto(out *ManagedSecurityGroups) { + *out = *in + if in.AllNodesSecurityGroupRules != nil { + in, out := &in.AllNodesSecurityGroupRules, &out.AllNodesSecurityGroupRules + *out = make([]SecurityGroupRuleSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedSecurityGroups. +func (in *ManagedSecurityGroups) DeepCopy() *ManagedSecurityGroups { + if in == nil { + return nil + } + out := new(ManagedSecurityGroups) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkFilter) DeepCopyInto(out *NetworkFilter) { + *out = *in + in.FilterByNeutronTags.DeepCopyInto(&out.FilterByNeutronTags) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkFilter. +func (in *NetworkFilter) DeepCopy() *NetworkFilter { + if in == nil { + return nil + } + out := new(NetworkFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkParam) DeepCopyInto(out *NetworkParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(NetworkFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkParam. +func (in *NetworkParam) DeepCopy() *NetworkParam { + if in == nil { + return nil + } + out := new(NetworkParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkStatus) DeepCopyInto(out *NetworkStatus) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkStatus. +func (in *NetworkStatus) DeepCopy() *NetworkStatus { + if in == nil { + return nil + } + out := new(NetworkStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkStatusWithSubnets) DeepCopyInto(out *NetworkStatusWithSubnets) { + *out = *in + in.NetworkStatus.DeepCopyInto(&out.NetworkStatus) + if in.Subnets != nil { + in, out := &in.Subnets, &out.Subnets + *out = make([]Subnet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkStatusWithSubnets. +func (in *NetworkStatusWithSubnets) DeepCopy() *NetworkStatusWithSubnets { + if in == nil { + return nil + } + out := new(NetworkStatusWithSubnets) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackCluster) DeepCopyInto(out *OpenStackCluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackCluster. +func (in *OpenStackCluster) DeepCopy() *OpenStackCluster { + if in == nil { + return nil + } + out := new(OpenStackCluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackCluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterList) DeepCopyInto(out *OpenStackClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackCluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterList. +func (in *OpenStackClusterList) DeepCopy() *OpenStackClusterList { + if in == nil { + return nil + } + out := new(OpenStackClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterSpec) DeepCopyInto(out *OpenStackClusterSpec) { + *out = *in + if in.ManagedSubnets != nil { + in, out := &in.ManagedSubnets, &out.ManagedSubnets + *out = make([]SubnetSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Router != nil { + in, out := &in.Router, &out.Router + *out = new(RouterParam) + (*in).DeepCopyInto(*out) + } + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkParam) + (*in).DeepCopyInto(*out) + } + if in.Subnets != nil { + in, out := &in.Subnets, &out.Subnets + *out = make([]SubnetParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NetworkMTU != nil { + in, out := &in.NetworkMTU, &out.NetworkMTU + *out = new(int) + **out = **in + } + if in.ExternalRouterIPs != nil { + in, out := &in.ExternalRouterIPs, &out.ExternalRouterIPs + *out = make([]ExternalRouterIPParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExternalNetwork != nil { + in, out := &in.ExternalNetwork, &out.ExternalNetwork + *out = new(NetworkParam) + (*in).DeepCopyInto(*out) + } + if in.DisableExternalNetwork != nil { + in, out := &in.DisableExternalNetwork, &out.DisableExternalNetwork + *out = new(bool) + **out = **in + } + if in.APIServerLoadBalancer != nil { + in, out := &in.APIServerLoadBalancer, &out.APIServerLoadBalancer + *out = new(APIServerLoadBalancer) + (*in).DeepCopyInto(*out) + } + if in.DisableAPIServerFloatingIP != nil { + in, out := &in.DisableAPIServerFloatingIP, &out.DisableAPIServerFloatingIP + *out = new(bool) + **out = **in + } + if in.APIServerFloatingIP != nil { + in, out := &in.APIServerFloatingIP, &out.APIServerFloatingIP + *out = new(string) + **out = **in + } + if in.APIServerFixedIP != nil { + in, out := &in.APIServerFixedIP, &out.APIServerFixedIP + *out = new(string) + **out = **in + } + if in.APIServerPort != nil { + in, out := &in.APIServerPort, &out.APIServerPort + *out = new(int) + **out = **in + } + if in.ManagedSecurityGroups != nil { + in, out := &in.ManagedSecurityGroups, &out.ManagedSecurityGroups + *out = new(ManagedSecurityGroups) + (*in).DeepCopyInto(*out) + } + if in.DisablePortSecurity != nil { + in, out := &in.DisablePortSecurity, &out.DisablePortSecurity + *out = new(bool) + **out = **in + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ControlPlaneEndpoint != nil { + in, out := &in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint + *out = new(apiv1beta1.APIEndpoint) + **out = **in + } + if in.ControlPlaneAvailabilityZones != nil { + in, out := &in.ControlPlaneAvailabilityZones, &out.ControlPlaneAvailabilityZones + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ControlPlaneOmitAvailabilityZone != nil { + in, out := &in.ControlPlaneOmitAvailabilityZone, &out.ControlPlaneOmitAvailabilityZone + *out = new(bool) + **out = **in + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(Bastion) + (*in).DeepCopyInto(*out) + } + out.IdentityRef = in.IdentityRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterSpec. +func (in *OpenStackClusterSpec) DeepCopy() *OpenStackClusterSpec { + if in == nil { + return nil + } + out := new(OpenStackClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterStatus) DeepCopyInto(out *OpenStackClusterStatus) { + *out = *in + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkStatusWithSubnets) + (*in).DeepCopyInto(*out) + } + if in.ExternalNetwork != nil { + in, out := &in.ExternalNetwork, &out.ExternalNetwork + *out = new(NetworkStatus) + (*in).DeepCopyInto(*out) + } + if in.Router != nil { + in, out := &in.Router, &out.Router + *out = new(Router) + (*in).DeepCopyInto(*out) + } + if in.APIServerLoadBalancer != nil { + in, out := &in.APIServerLoadBalancer, &out.APIServerLoadBalancer + *out = new(LoadBalancer) + (*in).DeepCopyInto(*out) + } + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(apiv1beta1.FailureDomains, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.ControlPlaneSecurityGroup != nil { + in, out := &in.ControlPlaneSecurityGroup, &out.ControlPlaneSecurityGroup + *out = new(SecurityGroupStatus) + **out = **in + } + if in.WorkerSecurityGroup != nil { + in, out := &in.WorkerSecurityGroup, &out.WorkerSecurityGroup + *out = new(SecurityGroupStatus) + **out = **in + } + if in.BastionSecurityGroup != nil { + in, out := &in.BastionSecurityGroup, &out.BastionSecurityGroup + *out = new(SecurityGroupStatus) + **out = **in + } + if in.Bastion != nil { + in, out := &in.Bastion, &out.Bastion + *out = new(BastionStatus) + (*in).DeepCopyInto(*out) + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.ClusterStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterStatus. +func (in *OpenStackClusterStatus) DeepCopy() *OpenStackClusterStatus { + if in == nil { + return nil + } + out := new(OpenStackClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplate) DeepCopyInto(out *OpenStackClusterTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplate. +func (in *OpenStackClusterTemplate) DeepCopy() *OpenStackClusterTemplate { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackClusterTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplateList) DeepCopyInto(out *OpenStackClusterTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackClusterTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateList. +func (in *OpenStackClusterTemplateList) DeepCopy() *OpenStackClusterTemplateList { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackClusterTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplateResource) DeepCopyInto(out *OpenStackClusterTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateResource. +func (in *OpenStackClusterTemplateResource) DeepCopy() *OpenStackClusterTemplateResource { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackClusterTemplateSpec) DeepCopyInto(out *OpenStackClusterTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackClusterTemplateSpec. +func (in *OpenStackClusterTemplateSpec) DeepCopy() *OpenStackClusterTemplateSpec { + if in == nil { + return nil + } + out := new(OpenStackClusterTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackIdentityReference) DeepCopyInto(out *OpenStackIdentityReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackIdentityReference. +func (in *OpenStackIdentityReference) DeepCopy() *OpenStackIdentityReference { + if in == nil { + return nil + } + out := new(OpenStackIdentityReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachine) DeepCopyInto(out *OpenStackMachine) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachine. +func (in *OpenStackMachine) DeepCopy() *OpenStackMachine { + if in == nil { + return nil + } + out := new(OpenStackMachine) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackMachine) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineList) DeepCopyInto(out *OpenStackMachineList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackMachine, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineList. +func (in *OpenStackMachineList) DeepCopy() *OpenStackMachineList { + if in == nil { + return nil + } + out := new(OpenStackMachineList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackMachineList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineSpec) DeepCopyInto(out *OpenStackMachineSpec) { + *out = *in + if in.ProviderID != nil { + in, out := &in.ProviderID, &out.ProviderID + *out = new(string) + **out = **in + } + in.Image.DeepCopyInto(&out.Image) + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]PortOpts, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]SecurityGroupParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ServerMetadata != nil { + in, out := &in.ServerMetadata, &out.ServerMetadata + *out = make([]ServerMetadata, len(*in)) + copy(*out, *in) + } + if in.ConfigDrive != nil { + in, out := &in.ConfigDrive, &out.ConfigDrive + *out = new(bool) + **out = **in + } + if in.RootVolume != nil { + in, out := &in.RootVolume, &out.RootVolume + *out = new(RootVolume) + (*in).DeepCopyInto(*out) + } + if in.AdditionalBlockDevices != nil { + in, out := &in.AdditionalBlockDevices, &out.AdditionalBlockDevices + *out = make([]AdditionalBlockDevice, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ServerGroup != nil { + in, out := &in.ServerGroup, &out.ServerGroup + *out = new(ServerGroupParam) + (*in).DeepCopyInto(*out) + } + if in.IdentityRef != nil { + in, out := &in.IdentityRef, &out.IdentityRef + *out = new(OpenStackIdentityReference) + **out = **in + } + if in.FloatingIPPoolRef != nil { + in, out := &in.FloatingIPPoolRef, &out.FloatingIPPoolRef + *out = new(v1.TypedLocalObjectReference) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineSpec. +func (in *OpenStackMachineSpec) DeepCopy() *OpenStackMachineSpec { + if in == nil { + return nil + } + out := new(OpenStackMachineSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineStatus) DeepCopyInto(out *OpenStackMachineStatus) { + *out = *in + if in.InstanceID != nil { + in, out := &in.InstanceID, &out.InstanceID + *out = new(string) + **out = **in + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]v1.NodeAddress, len(*in)) + copy(*out, *in) + } + if in.InstanceState != nil { + in, out := &in.InstanceState, &out.InstanceState + *out = new(InstanceState) + **out = **in + } + if in.Resolved != nil { + in, out := &in.Resolved, &out.Resolved + *out = new(ResolvedMachineSpec) + (*in).DeepCopyInto(*out) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(MachineResources) + (*in).DeepCopyInto(*out) + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachineStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineStatus. +func (in *OpenStackMachineStatus) DeepCopy() *OpenStackMachineStatus { + if in == nil { + return nil + } + out := new(OpenStackMachineStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineTemplate) DeepCopyInto(out *OpenStackMachineTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineTemplate. +func (in *OpenStackMachineTemplate) DeepCopy() *OpenStackMachineTemplate { + if in == nil { + return nil + } + out := new(OpenStackMachineTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackMachineTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineTemplateList) DeepCopyInto(out *OpenStackMachineTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenStackMachineTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineTemplateList. +func (in *OpenStackMachineTemplateList) DeepCopy() *OpenStackMachineTemplateList { + if in == nil { + return nil + } + out := new(OpenStackMachineTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenStackMachineTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineTemplateResource) DeepCopyInto(out *OpenStackMachineTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineTemplateResource. +func (in *OpenStackMachineTemplateResource) DeepCopy() *OpenStackMachineTemplateResource { + if in == nil { + return nil + } + out := new(OpenStackMachineTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenStackMachineTemplateSpec) DeepCopyInto(out *OpenStackMachineTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackMachineTemplateSpec. +func (in *OpenStackMachineTemplateSpec) DeepCopy() *OpenStackMachineTemplateSpec { + if in == nil { + return nil + } + out := new(OpenStackMachineTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PortOpts) DeepCopyInto(out *PortOpts) { + *out = *in + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkParam) + (*in).DeepCopyInto(*out) + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.NameSuffix != nil { + in, out := &in.NameSuffix, &out.NameSuffix + *out = new(string) + **out = **in + } + if in.FixedIPs != nil { + in, out := &in.FixedIPs, &out.FixedIPs + *out = make([]FixedIP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]SecurityGroupParam, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Trunk != nil { + in, out := &in.Trunk, &out.Trunk + *out = new(bool) + **out = **in + } + in.ResolvedPortSpecFields.DeepCopyInto(&out.ResolvedPortSpecFields) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortOpts. +func (in *PortOpts) DeepCopy() *PortOpts { + if in == nil { + return nil + } + out := new(PortOpts) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PortStatus) DeepCopyInto(out *PortStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PortStatus. +func (in *PortStatus) DeepCopy() *PortStatus { + if in == nil { + return nil + } + out := new(PortStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResolvedFixedIP) DeepCopyInto(out *ResolvedFixedIP) { + *out = *in + if in.SubnetID != nil { + in, out := &in.SubnetID, &out.SubnetID + *out = new(string) + **out = **in + } + if in.IPAddress != nil { + in, out := &in.IPAddress, &out.IPAddress + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResolvedFixedIP. +func (in *ResolvedFixedIP) DeepCopy() *ResolvedFixedIP { + if in == nil { + return nil + } + out := new(ResolvedFixedIP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResolvedMachineSpec) DeepCopyInto(out *ResolvedMachineSpec) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]ResolvedPortSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResolvedMachineSpec. +func (in *ResolvedMachineSpec) DeepCopy() *ResolvedMachineSpec { + if in == nil { + return nil + } + out := new(ResolvedMachineSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResolvedPortSpec) DeepCopyInto(out *ResolvedPortSpec) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Trunk != nil { + in, out := &in.Trunk, &out.Trunk + *out = new(bool) + **out = **in + } + if in.FixedIPs != nil { + in, out := &in.FixedIPs, &out.FixedIPs + *out = make([]ResolvedFixedIP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.ResolvedPortSpecFields.DeepCopyInto(&out.ResolvedPortSpecFields) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResolvedPortSpec. +func (in *ResolvedPortSpec) DeepCopy() *ResolvedPortSpec { + if in == nil { + return nil + } + out := new(ResolvedPortSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResolvedPortSpecFields) DeepCopyInto(out *ResolvedPortSpecFields) { + *out = *in + if in.AdminStateUp != nil { + in, out := &in.AdminStateUp, &out.AdminStateUp + *out = new(bool) + **out = **in + } + if in.MACAddress != nil { + in, out := &in.MACAddress, &out.MACAddress + *out = new(string) + **out = **in + } + if in.AllowedAddressPairs != nil { + in, out := &in.AllowedAddressPairs, &out.AllowedAddressPairs + *out = make([]AddressPair, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.HostID != nil { + in, out := &in.HostID, &out.HostID + *out = new(string) + **out = **in + } + if in.VNICType != nil { + in, out := &in.VNICType, &out.VNICType + *out = new(string) + **out = **in + } + if in.Profile != nil { + in, out := &in.Profile, &out.Profile + *out = new(BindingProfile) + (*in).DeepCopyInto(*out) + } + if in.DisablePortSecurity != nil { + in, out := &in.DisablePortSecurity, &out.DisablePortSecurity + *out = new(bool) + **out = **in + } + if in.PropagateUplinkStatus != nil { + in, out := &in.PropagateUplinkStatus, &out.PropagateUplinkStatus + *out = new(bool) + **out = **in + } + if in.ValueSpecs != nil { + in, out := &in.ValueSpecs, &out.ValueSpecs + *out = make([]ValueSpec, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResolvedPortSpecFields. +func (in *ResolvedPortSpecFields) DeepCopy() *ResolvedPortSpecFields { + if in == nil { + return nil + } + out := new(ResolvedPortSpecFields) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RootVolume) DeepCopyInto(out *RootVolume) { + *out = *in + in.BlockDeviceVolume.DeepCopyInto(&out.BlockDeviceVolume) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RootVolume. +func (in *RootVolume) DeepCopy() *RootVolume { + if in == nil { + return nil + } + out := new(RootVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Router) DeepCopyInto(out *Router) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.IPs != nil { + in, out := &in.IPs, &out.IPs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Router. +func (in *Router) DeepCopy() *Router { + if in == nil { + return nil + } + out := new(Router) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouterFilter) DeepCopyInto(out *RouterFilter) { + *out = *in + in.FilterByNeutronTags.DeepCopyInto(&out.FilterByNeutronTags) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouterFilter. +func (in *RouterFilter) DeepCopy() *RouterFilter { + if in == nil { + return nil + } + out := new(RouterFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouterParam) DeepCopyInto(out *RouterParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(RouterFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouterParam. +func (in *RouterParam) DeepCopy() *RouterParam { + if in == nil { + return nil + } + out := new(RouterParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupFilter) DeepCopyInto(out *SecurityGroupFilter) { + *out = *in + in.FilterByNeutronTags.DeepCopyInto(&out.FilterByNeutronTags) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupFilter. +func (in *SecurityGroupFilter) DeepCopy() *SecurityGroupFilter { + if in == nil { + return nil + } + out := new(SecurityGroupFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupParam) DeepCopyInto(out *SecurityGroupParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(SecurityGroupFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupParam. +func (in *SecurityGroupParam) DeepCopy() *SecurityGroupParam { + if in == nil { + return nil + } + out := new(SecurityGroupParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupRuleSpec) DeepCopyInto(out *SecurityGroupRuleSpec) { + *out = *in + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.EtherType != nil { + in, out := &in.EtherType, &out.EtherType + *out = new(string) + **out = **in + } + if in.PortRangeMin != nil { + in, out := &in.PortRangeMin, &out.PortRangeMin + *out = new(int) + **out = **in + } + if in.PortRangeMax != nil { + in, out := &in.PortRangeMax, &out.PortRangeMax + *out = new(int) + **out = **in + } + if in.Protocol != nil { + in, out := &in.Protocol, &out.Protocol + *out = new(string) + **out = **in + } + if in.RemoteGroupID != nil { + in, out := &in.RemoteGroupID, &out.RemoteGroupID + *out = new(string) + **out = **in + } + if in.RemoteIPPrefix != nil { + in, out := &in.RemoteIPPrefix, &out.RemoteIPPrefix + *out = new(string) + **out = **in + } + if in.RemoteManagedGroups != nil { + in, out := &in.RemoteManagedGroups, &out.RemoteManagedGroups + *out = make([]ManagedSecurityGroupName, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupRuleSpec. +func (in *SecurityGroupRuleSpec) DeepCopy() *SecurityGroupRuleSpec { + if in == nil { + return nil + } + out := new(SecurityGroupRuleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityGroupStatus) DeepCopyInto(out *SecurityGroupStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityGroupStatus. +func (in *SecurityGroupStatus) DeepCopy() *SecurityGroupStatus { + if in == nil { + return nil + } + out := new(SecurityGroupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerGroupFilter) DeepCopyInto(out *ServerGroupFilter) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerGroupFilter. +func (in *ServerGroupFilter) DeepCopy() *ServerGroupFilter { + if in == nil { + return nil + } + out := new(ServerGroupFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerGroupParam) DeepCopyInto(out *ServerGroupParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(ServerGroupFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerGroupParam. +func (in *ServerGroupParam) DeepCopy() *ServerGroupParam { + if in == nil { + return nil + } + out := new(ServerGroupParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerMetadata) DeepCopyInto(out *ServerMetadata) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerMetadata. +func (in *ServerMetadata) DeepCopy() *ServerMetadata { + if in == nil { + return nil + } + out := new(ServerMetadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subnet) DeepCopyInto(out *Subnet) { + *out = *in + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subnet. +func (in *Subnet) DeepCopy() *Subnet { + if in == nil { + return nil + } + out := new(Subnet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetFilter) DeepCopyInto(out *SubnetFilter) { + *out = *in + in.FilterByNeutronTags.DeepCopyInto(&out.FilterByNeutronTags) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetFilter. +func (in *SubnetFilter) DeepCopy() *SubnetFilter { + if in == nil { + return nil + } + out := new(SubnetFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetParam) DeepCopyInto(out *SubnetParam) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(SubnetFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetParam. +func (in *SubnetParam) DeepCopy() *SubnetParam { + if in == nil { + return nil + } + out := new(SubnetParam) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubnetSpec) DeepCopyInto(out *SubnetSpec) { + *out = *in + if in.DNSNameservers != nil { + in, out := &in.DNSNameservers, &out.DNSNameservers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AllocationPools != nil { + in, out := &in.AllocationPools, &out.AllocationPools + *out = make([]AllocationPool, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubnetSpec. +func (in *SubnetSpec) DeepCopy() *SubnetSpec { + if in == nil { + return nil + } + out := new(SubnetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ValueSpec) DeepCopyInto(out *ValueSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ValueSpec. +func (in *ValueSpec) DeepCopy() *ValueSpec { + if in == nil { + return nil + } + out := new(ValueSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeAvailabilityZone) DeepCopyInto(out *VolumeAvailabilityZone) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(VolumeAZName) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeAvailabilityZone. +func (in *VolumeAvailabilityZone) DeepCopy() *VolumeAvailabilityZone { + if in == nil { + return nil + } + out := new(VolumeAvailabilityZone) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion/restore.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion/restore.go new file mode 100644 index 00000000..5b0477d3 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversion/restore.go @@ -0,0 +1,268 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package conversion + +import ( + "bytes" + "encoding/json" + "hash/crc64" + "reflect" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + hashutils "k8s.io/kubernetes/pkg/util/hash" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +// RestorerFor holds all field restorers for a given type T. +type RestorerFor[T metav1.Object] map[string]FieldRestorerFor[T] + +type FieldRestorerFor[T any] interface { + marshalState(T, T) (json.RawMessage, error) + restore(json.RawMessage, T) error +} + +// HashedFieldRestorerOpt is a modifier which adds optional behaviour to a +// HashedFieldRestorer. It can be passed as an argument to +// HashedFieldRestorer(). +type HashedFieldRestorerOpt[T, F any] func(*hashedFieldRestorer[T, F]) + +// HashedFieldRestorer restores a field to its original pre-conversion state +// only if it was not modified while converted. It does this by doing a full +// round-trip conversion before saving its state, and storing the hash of an +// unmodified round-trip converted object. +// +// HashedFieldRestorer takes 2 type arguments: +// +// T: The type of the object being converted. This is a pointer type. +// F: The type of the field in T which is being restored. This is not a +// pointer type. +// +// The type arguments can usually be omitted, as they can be inferred from the +// arguments. +// +// HashedFieldRestorer takes 2 arguments: +// +// getField: A function which takes the object being converted (of type T) and returns a pointer to the field being restored (of type *F). +// restoreField: Described below. +// +// restoreField is used to restore parts of the field to their original +// pre-conversion state which were not restored by the normal conversion +// functions. This is to preserve idempotency when the normal conversion +// functions are lossy, so it is only called if the field was not modified +// during conversion. +// +// restoreField takes 2 arguments: +// +// previous: A pointer to the saved original state of the field before conversion. +// dst: A pointer to the field which needs to be updated. +// +// The normal conversion functions should do as much work as possible, so +// restoreField should only be used to restore state which cannot be restored +// any other way. +func HashedFieldRestorer[T, F any](getField func(T) *F, restoreField func(*F, *F), opts ...HashedFieldRestorerOpt[T, F]) FieldRestorerFor[T] { + restorer := hashedFieldRestorer[T, F]{ + getField: getField, + restoreField: restoreField, + } + for _, opt := range opts { + opt(&restorer) + } + + return restorer +} + +// HashedFilterField adds a field filter to a HashedFieldRestorer. The field +// filter returns a modified copy of the field to be used for comparison. This +// can be used to ignore certain changes during comparison. +func HashedFilterField[T, F any](f func(*F) *F) func(*hashedFieldRestorer[T, F]) { + return func(r *hashedFieldRestorer[T, F]) { + r.filterField = f + } +} + +type hashedFieldRestorer[T any, F any] struct { + // getField returns the field to be restored + getField func(T) *F + + // restoreField restores the field to its original pre-conversion state + restoreField func(*F, *F) + + // filterField returns a modified copy of the field to be used for comparison. i.e. filtered fields will be ignored in comparison. + filterField func(*F) *F +} + +var _ FieldRestorerFor[any] = hashedFieldRestorer[any, any]{} + +//nolint:unused +type hashedFieldRestoreState struct { + Hash []byte `json:"h,omitempty"` + Data json.RawMessage `json:"d,omitempty"` +} + +//nolint:unused +func (r hashedFieldRestorer[T, F]) getHash(obj T) []byte { + f := r.getField(obj) + if r.filterField != nil { + f = r.filterField(f) + } + + table := crc64.MakeTable(crc64.ECMA) + hash := crc64.New(table) + hashutils.DeepHashObject(hash, f) + return hash.Sum(make([]byte, 0, 8)) +} + +//nolint:unused +func (r hashedFieldRestorer[T, F]) marshalState(src, compare T) (json.RawMessage, error) { + f := r.getField(src) + if r.filterField != nil { + f = r.filterField(f) + } + + b, err := json.Marshal(f) + if err != nil { + return nil, err + } + + srcHash := r.getHash(src) + cmpHash := r.getHash(compare) + if bytes.Equal(srcHash, cmpHash) { + return nil, nil + } + + restoreState := hashedFieldRestoreState{ + Hash: cmpHash, + Data: b, + } + return json.Marshal(restoreState) +} + +//nolint:unused +func (r hashedFieldRestorer[T, F]) restore(b json.RawMessage, dst T) error { + var restoreState hashedFieldRestoreState + if err := json.Unmarshal(b, &restoreState); err != nil { + return err + } + + if bytes.Equal(r.getHash(dst), restoreState.Hash) { + var previous F + if err := json.Unmarshal(restoreState.Data, &previous); err != nil { + return err + } + r.restoreField(&previous, r.getField(dst)) + } + + return nil +} + +// UnconditionalFieldRestorer restores a field to its previous value without checking to see if it was modified during conversion. +func UnconditionalFieldRestorer[T, F any](getField func(T) *F) FieldRestorerFor[T] { + return unconditionalFieldRestorer[T, F]{ + getField: getField, + } +} + +type unconditionalFieldRestorer[T any, F any] struct { + getField func(T) *F +} + +var _ FieldRestorerFor[any] = unconditionalFieldRestorer[any, any]{} + +//nolint:unused +type unconditionalFieldRestoreState json.RawMessage + +//nolint:unused +func (r unconditionalFieldRestorer[T, F]) marshalState(src, _ T) (json.RawMessage, error) { + f := r.getField(src) + + // We could do this with a comparable constraint on F, but that's too restrictive for an arbitrary struct. + if f == nil || reflect.ValueOf(f).Elem().IsZero() { + return nil, nil + } + + return json.Marshal(r.getField(src)) +} + +//nolint:unused +func (r unconditionalFieldRestorer[T, F]) restore(b json.RawMessage, dst T) error { + return json.Unmarshal(b, r.getField(dst)) +} + +// restoreData serialises state for a set of restorers. +type restoreData map[string]json.RawMessage + +type pointerToObject[T any] interface { + *T + metav1.Object +} + +// ConvertAndRestore converts src to dst. During conversion is reads and uses any restore data in the src annotation, and writes new restore data to the dst annotation. +func ConvertAndRestore[S pointerToObject[SO], SO any, D metav1.Object](src S, dst D, convert func(S, D, conversion.Scope) error, unconvert func(D, S, conversion.Scope) error, srcRestorer RestorerFor[S], dstRestorer RestorerFor[D]) error { + var dstRestoreData restoreData + srcAnnotations := src.GetAnnotations() + if srcData, ok := srcAnnotations[utilconversion.DataAnnotation]; ok { + dstRestoreData = make(restoreData) + if err := json.Unmarshal([]byte(srcData), &dstRestoreData); err != nil { + return err + } + } + + if err := convert(src, dst, nil); err != nil { + return err + } + + compare := new(SO) + if err := unconvert(dst, compare, nil); err != nil { + return err + } + + for field, restoreData := range dstRestoreData { + if restorer, ok := dstRestorer[field]; ok { + if err := restorer.restore(restoreData, dst); err != nil { + return err + } + } + } + + srcRestoreData := make(restoreData) + for field, restorer := range srcRestorer { + restoreData, err := restorer.marshalState(src, compare) + if err != nil { + return err + } + if restoreData != nil { + srcRestoreData[field] = restoreData + } + } + + if len(srcRestoreData) > 0 { + restoreData, err := json.Marshal(srcRestoreData) + if err != nil { + return err + } + + dstAnnotations := dst.GetAnnotations() + if dstAnnotations == nil { + dstAnnotations = map[string]string{} + } + dstAnnotations[utilconversion.DataAnnotation] = string(restoreData) + dst.SetAnnotations(dstAnnotations) + } + + return nil +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon/volumeavailabilityzone.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon/volumeavailabilityzone.go new file mode 100644 index 00000000..520a213a --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/conversioncommon/volumeavailabilityzone.go @@ -0,0 +1,62 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package conversioncommon + +import ( + "k8s.io/apimachinery/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1" +) + +func Convert_string_To_Pointer_v1beta1_VolumeAvailabilityZone(in *string, out **infrav1.VolumeAvailabilityZone, _ conversion.Scope) error { + switch *in { + case "": + *out = &infrav1.VolumeAvailabilityZone{ + From: infrav1.VolumeAZFromMachine, + } + default: + azName := infrav1.VolumeAZName(*in) + *out = &infrav1.VolumeAvailabilityZone{ + From: infrav1.VolumeAZFromName, + Name: &azName, + } + } + + return nil +} + +func Convert_Pointer_v1beta1_VolumeAvailabilityZone_To_string(in **infrav1.VolumeAvailabilityZone, out *string, _ conversion.Scope) error { + // This is a lossy: can't specify no AZ prior to v1beta1 + if *in == nil { + *out = "" + return nil + } + + switch (*in).From { + case "", infrav1.VolumeAZFromName: + name := (*in).Name + if name != nil { + *out = string(*name) + } else { + *out = "" + } + case infrav1.VolumeAZFromMachine: + *out = "" + } + + return nil +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/conversion.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/conversion.go new file mode 100644 index 00000000..9e98c991 --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/conversion.go @@ -0,0 +1,97 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package optional + +import ( + "k8s.io/apimachinery/pkg/conversion" +) + +func RestoreString(previous, dst *String) { + if *dst == nil || **dst == "" { + *dst = *previous + } +} + +func RestoreInt(previous, dst *Int) { + if *dst == nil || **dst == 0 { + *dst = *previous + } +} + +func RestoreBool(previous, dst *Bool) { + if *dst == nil || !**dst { + *dst = *previous + } +} + +func Convert_string_To_optional_String(in *string, out *String, _ conversion.Scope) error { + // NOTE: This function has the opposite defaulting behaviour to + // Convert_string_to_Pointer_string defined in apimachinery: it converts + // empty strings to nil instead of a pointer to an empty string. + + if *in == "" { + *out = nil + } else { + *out = in + } + return nil +} + +func Convert_optional_String_To_string(in *String, out *string, _ conversion.Scope) error { + if *in == nil { + *out = "" + } else { + *out = **in + } + return nil +} + +func Convert_int_To_optional_Int(in *int, out *Int, _ conversion.Scope) error { + if *in == 0 { + *out = nil + } else { + *out = in + } + return nil +} + +func Convert_optional_Int_To_int(in *Int, out *int, _ conversion.Scope) error { + if *in == nil { + *out = 0 + } else { + *out = **in + } + return nil +} + +func Convert_bool_To_optional_Bool(in *bool, out *Bool, _ conversion.Scope) error { + if !*in { + *out = nil + } else { + *out = in + } + return nil +} + +func Convert_optional_Bool_To_bool(in *Bool, out *bool, _ conversion.Scope) error { + if *in == nil { + *out = false + } else { + *out = **in + } + return nil +} diff --git a/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/types.go b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/types.go new file mode 100644 index 00000000..37815bfb --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/optional/types.go @@ -0,0 +1,34 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package optional + +// String is a string that can be unspecified. strings which are converted to +// optional.String during API conversion will be converted to nil if the value +// was previously the empty string. +// +optional. +type String *string + +// Int is an int that can be unspecified. ints which are converted to +// optional.Int during API conversion will be converted to nil if the value +// was previously 0. +// +optional. +type Int *int + +// Bool is a bool that can be unspecified. bools which are converted to +// optional.Bool during API conversion will be converted to nil if the value +// was previously false. +type Bool *bool diff --git a/vendor/sigs.k8s.io/cluster-api/util/conversion/conversion.go b/vendor/sigs.k8s.io/cluster-api/util/conversion/conversion.go new file mode 100644 index 00000000..561cf69d --- /dev/null +++ b/vendor/sigs.k8s.io/cluster-api/util/conversion/conversion.go @@ -0,0 +1,245 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package conversion implements conversion utilities. +package conversion + +import ( + "context" + "math/rand" + "sort" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + fuzz "github.com/google/gofuzz" + "github.com/onsi/gomega" + "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + apiequality "k8s.io/apimachinery/pkg/api/equality" + metafuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/apimachinery/pkg/util/json" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/util" +) + +const ( + // DataAnnotation is the annotation that conversion webhooks + // use to retain the data in case of down-conversion from the hub. + DataAnnotation = "cluster.x-k8s.io/conversion-data" +) + +var ( + contract = clusterv1.GroupVersion.String() +) + +// UpdateReferenceAPIContract takes a client and object reference, queries the API Server for +// the Custom Resource Definition and looks which one is the stored version available. +// +// The object passed as input is modified in place if an updated compatible version is found. +// NOTE: This version depends on CRDs being named correctly as defined by contract.CalculateCRDName. +func UpdateReferenceAPIContract(ctx context.Context, c client.Client, ref *corev1.ObjectReference) error { + gvk := ref.GroupVersionKind() + + metadata, err := util.GetGVKMetadata(ctx, c, gvk) + if err != nil { + return errors.Wrapf(err, "failed to update apiVersion in ref") + } + + chosen, err := getLatestAPIVersionFromContract(metadata) + if err != nil { + return errors.Wrapf(err, "failed to update apiVersion in ref") + } + + // Modify the GroupVersionKind with the new version. + if gvk.Version != chosen { + gvk.Version = chosen + ref.SetGroupVersionKind(gvk) + } + + return nil +} + +func getLatestAPIVersionFromContract(metadata metav1.Object) (string, error) { + labels := metadata.GetLabels() + + // If there is no label, return early without changing the reference. + supportedVersions, ok := labels[contract] + if !ok || supportedVersions == "" { + return "", errors.Errorf("cannot find any versions matching contract %q for CRD %v as contract version label(s) are either missing or empty (see https://cluster-api.sigs.k8s.io/developer/providers/contracts.html#api-version-labels)", contract, metadata.GetName()) + } + + // Pick the latest version in the slice and validate it. + kubeVersions := util.KubeAwareAPIVersions(strings.Split(supportedVersions, "_")) + sort.Sort(kubeVersions) + return kubeVersions[len(kubeVersions)-1], nil +} + +// MarshalData stores the source object as json data in the destination object annotations map. +// It ignores the metadata of the source object. +func MarshalData(src metav1.Object, dst metav1.Object) error { + u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(src) + if err != nil { + return err + } + delete(u, "metadata") + + data, err := json.Marshal(u) + if err != nil { + return err + } + annotations := dst.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + annotations[DataAnnotation] = string(data) + dst.SetAnnotations(annotations) + return nil +} + +// UnmarshalData tries to retrieve the data from the annotation and unmarshals it into the object passed as input. +func UnmarshalData(from metav1.Object, to interface{}) (bool, error) { + annotations := from.GetAnnotations() + data, ok := annotations[DataAnnotation] + if !ok { + return false, nil + } + if err := json.Unmarshal([]byte(data), to); err != nil { + return false, err + } + delete(annotations, DataAnnotation) + from.SetAnnotations(annotations) + return true, nil +} + +// GetFuzzer returns a new fuzzer to be used for testing. +func GetFuzzer(scheme *runtime.Scheme, funcs ...fuzzer.FuzzerFuncs) *fuzz.Fuzzer { + funcs = append([]fuzzer.FuzzerFuncs{ + metafuzzer.Funcs, + func(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + // Custom fuzzer for metav1.Time pointers which weren't + // fuzzed and always resulted in `nil` values. + // This implementation is somewhat similar to the one provided + // in the metafuzzer.Funcs. + func(input *metav1.Time, c fuzz.Continue) { + if input != nil { + var sec, nsec uint32 + c.Fuzz(&sec) + c.Fuzz(&nsec) + fuzzed := metav1.Unix(int64(sec), int64(nsec)).Rfc3339Copy() + input.Time = fuzzed.Time + } + }, + } + }, + }, funcs...) + return fuzzer.FuzzerFor( + fuzzer.MergeFuzzerFuncs(funcs...), + rand.NewSource(rand.Int63()), //nolint:gosec + runtimeserializer.NewCodecFactory(scheme), + ) +} + +// FuzzTestFuncInput contains input parameters +// for the FuzzTestFunc function. +type FuzzTestFuncInput struct { + Scheme *runtime.Scheme + + Hub conversion.Hub + HubAfterMutation func(conversion.Hub) + + Spoke conversion.Convertible + SpokeAfterMutation func(convertible conversion.Convertible) + SkipSpokeAnnotationCleanup bool + + FuzzerFuncs []fuzzer.FuzzerFuncs +} + +// FuzzTestFunc returns a new testing function to be used in tests to make sure conversions between +// the Hub version of an object and an older version aren't lossy. +func FuzzTestFunc(input FuzzTestFuncInput) func(*testing.T) { + if input.Scheme == nil { + input.Scheme = scheme.Scheme + } + + return func(t *testing.T) { + t.Helper() + t.Run("spoke-hub-spoke", func(t *testing.T) { + g := gomega.NewWithT(t) + fuzzer := GetFuzzer(input.Scheme, input.FuzzerFuncs...) + + for range 10000 { + // Create the spoke and fuzz it + spokeBefore := input.Spoke.DeepCopyObject().(conversion.Convertible) + fuzzer.Fuzz(spokeBefore) + + // First convert spoke to hub + hubCopy := input.Hub.DeepCopyObject().(conversion.Hub) + g.Expect(spokeBefore.ConvertTo(hubCopy)).To(gomega.Succeed()) + + // Convert hub back to spoke and check if the resulting spoke is equal to the spoke before the round trip + spokeAfter := input.Spoke.DeepCopyObject().(conversion.Convertible) + g.Expect(spokeAfter.ConvertFrom(hubCopy)).To(gomega.Succeed()) + + // Remove data annotation eventually added by ConvertFrom for avoiding data loss in hub-spoke-hub round trips + // NOTE: There are use case when we want to skip this operation, e.g. if the spoke object does not have ObjectMeta (e.g. kubeadm types). + if !input.SkipSpokeAnnotationCleanup { + metaAfter := spokeAfter.(metav1.Object) + delete(metaAfter.GetAnnotations(), DataAnnotation) + } + + if input.SpokeAfterMutation != nil { + input.SpokeAfterMutation(spokeAfter) + } + + g.Expect(apiequality.Semantic.DeepEqual(spokeBefore, spokeAfter)).To(gomega.BeTrue(), cmp.Diff(spokeBefore, spokeAfter)) + } + }) + t.Run("hub-spoke-hub", func(t *testing.T) { + g := gomega.NewWithT(t) + fuzzer := GetFuzzer(input.Scheme, input.FuzzerFuncs...) + + for range 10000 { + // Create the hub and fuzz it + hubBefore := input.Hub.DeepCopyObject().(conversion.Hub) + fuzzer.Fuzz(hubBefore) + + // First convert hub to spoke + dstCopy := input.Spoke.DeepCopyObject().(conversion.Convertible) + g.Expect(dstCopy.ConvertFrom(hubBefore)).To(gomega.Succeed()) + + // Convert spoke back to hub and check if the resulting hub is equal to the hub before the round trip + hubAfter := input.Hub.DeepCopyObject().(conversion.Hub) + g.Expect(dstCopy.ConvertTo(hubAfter)).To(gomega.Succeed()) + + if input.HubAfterMutation != nil { + input.HubAfterMutation(hubAfter) + } + + g.Expect(apiequality.Semantic.DeepEqual(hubBefore, hubAfter)).To(gomega.BeTrue(), cmp.Diff(hubBefore, hubAfter)) + } + }) + } +} diff --git a/vendor/sigs.k8s.io/cluster-api/util/topology/topology.go b/vendor/sigs.k8s.io/cluster-api/util/topology/topology.go deleted file mode 100644 index f1a9cb6c..00000000 --- a/vendor/sigs.k8s.io/cluster-api/util/topology/topology.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package topology implements topology utility functions. -package topology - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" -) - -// ShouldSkipImmutabilityChecks returns true if it is a dry-run request and the object has the -// TopologyDryRunAnnotation annotation set, false otherwise. -// This ensures that the immutability check is skipped only when dry-running and when the operations has been invoked by the topology controller. -// Instead, kubectl dry-run behavior remains consistent with the one user gets when doing kubectl apply (immutability is enforced). -func ShouldSkipImmutabilityChecks(req admission.Request, obj metav1.Object) bool { - // Check if the request is a dry-run - if req.DryRun == nil || !*req.DryRun { - return false - } - - if obj == nil { - return false - } - - // Check for the TopologyDryRunAnnotation - annotations := obj.GetAnnotations() - if annotations == nil { - return false - } - if _, ok := annotations[clusterv1.TopologyDryRunAnnotation]; ok { - return true - } - return false -}