Skip to content

Commit 02a3173

Browse files
authored
Merge pull request #1353 from shiftstack/1345-volume-support
🐛 Don't require cinder when not using volumes
2 parents 822d51e + 68474a1 commit 02a3173

28 files changed

+1092
-717
lines changed

pkg/clients/compute.go

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package clients
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/gophercloud/gophercloud"
23+
"github.com/gophercloud/gophercloud/openstack"
24+
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces"
25+
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
26+
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
27+
"github.com/gophercloud/utils/openstack/compute/v2/flavors"
28+
29+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/metrics"
30+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/scope"
31+
)
32+
33+
/*
34+
NovaMinimumMicroversion is the minimum Nova microversion supported by CAPO
35+
2.53 corresponds to OpenStack Pike
36+
37+
For the canonical description of Nova microversions, see
38+
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html
39+
40+
CAPO uses server tags, which were added in microversion 2.52.
41+
*/
42+
const NovaMinimumMicroversion = "2.53"
43+
44+
// ServerExt is the base gophercloud Server with extensions used by InstanceStatus.
45+
type ServerExt struct {
46+
servers.Server
47+
availabilityzones.ServerAvailabilityZoneExt
48+
}
49+
50+
type ComputeClient interface {
51+
ListAvailabilityZones() ([]availabilityzones.AvailabilityZone, error)
52+
53+
GetFlavorIDFromName(flavor string) (string, error)
54+
CreateServer(createOpts servers.CreateOptsBuilder) (*ServerExt, error)
55+
DeleteServer(serverID string) error
56+
GetServer(serverID string) (*ServerExt, error)
57+
ListServers(listOpts servers.ListOptsBuilder) ([]ServerExt, error)
58+
59+
ListAttachedInterfaces(serverID string) ([]attachinterfaces.Interface, error)
60+
DeleteAttachedInterface(serverID, portID string) error
61+
}
62+
63+
type computeClient struct{ client *gophercloud.ServiceClient }
64+
65+
// NewComputeClient returns a new compute client.
66+
func NewComputeClient(scope *scope.Scope) (ComputeClient, error) {
67+
compute, err := openstack.NewComputeV2(scope.ProviderClient, gophercloud.EndpointOpts{
68+
Region: scope.ProviderClientOpts.RegionName,
69+
})
70+
if err != nil {
71+
return nil, fmt.Errorf("failed to create compute service client: %v", err)
72+
}
73+
compute.Microversion = NovaMinimumMicroversion
74+
75+
return &computeClient{compute}, nil
76+
}
77+
78+
func (c computeClient) ListAvailabilityZones() ([]availabilityzones.AvailabilityZone, error) {
79+
mc := metrics.NewMetricPrometheusContext("availability_zone", "list")
80+
allPages, err := availabilityzones.List(c.client).AllPages()
81+
if mc.ObserveRequest(err) != nil {
82+
return nil, err
83+
}
84+
return availabilityzones.ExtractAvailabilityZones(allPages)
85+
}
86+
87+
func (c computeClient) GetFlavorIDFromName(flavor string) (string, error) {
88+
mc := metrics.NewMetricPrometheusContext("flavor", "get")
89+
flavorID, err := flavors.IDFromName(c.client, flavor)
90+
return flavorID, mc.ObserveRequest(err)
91+
}
92+
93+
func (c computeClient) CreateServer(createOpts servers.CreateOptsBuilder) (*ServerExt, error) {
94+
var server ServerExt
95+
mc := metrics.NewMetricPrometheusContext("server", "create")
96+
err := servers.Create(c.client, createOpts).ExtractInto(&server)
97+
if mc.ObserveRequest(err) != nil {
98+
return nil, err
99+
}
100+
return &server, nil
101+
}
102+
103+
func (c computeClient) DeleteServer(serverID string) error {
104+
mc := metrics.NewMetricPrometheusContext("server", "delete")
105+
err := servers.Delete(c.client, serverID).ExtractErr()
106+
return mc.ObserveRequestIgnoreNotFound(err)
107+
}
108+
109+
func (c computeClient) GetServer(serverID string) (*ServerExt, error) {
110+
var server ServerExt
111+
mc := metrics.NewMetricPrometheusContext("server", "get")
112+
err := servers.Get(c.client, serverID).ExtractInto(&server)
113+
if mc.ObserveRequestIgnoreNotFound(err) != nil {
114+
return nil, err
115+
}
116+
return &server, nil
117+
}
118+
119+
func (c computeClient) ListServers(listOpts servers.ListOptsBuilder) ([]ServerExt, error) {
120+
var serverList []ServerExt
121+
mc := metrics.NewMetricPrometheusContext("server", "list")
122+
allPages, err := servers.List(c.client, listOpts).AllPages()
123+
if mc.ObserveRequest(err) != nil {
124+
return nil, err
125+
}
126+
err = servers.ExtractServersInto(allPages, &serverList)
127+
return serverList, err
128+
}
129+
130+
func (c computeClient) ListAttachedInterfaces(serverID string) ([]attachinterfaces.Interface, error) {
131+
mc := metrics.NewMetricPrometheusContext("server_os_interface", "list")
132+
interfaces, err := attachinterfaces.List(c.client, serverID).AllPages()
133+
if mc.ObserveRequest(err) != nil {
134+
return nil, err
135+
}
136+
return attachinterfaces.ExtractInterfaces(interfaces)
137+
}
138+
139+
func (c computeClient) DeleteAttachedInterface(serverID, portID string) error {
140+
mc := metrics.NewMetricPrometheusContext("server_os_interface", "delete")
141+
err := attachinterfaces.Delete(c.client, serverID, portID).ExtractErr()
142+
return mc.ObserveRequestIgnoreNotFoundorConflict(err)
143+
}
144+
145+
type computeErrorClient struct{ error }
146+
147+
// NewComputeErrorClient returns a ComputeClient in which every method returns the given error.
148+
func NewComputeErrorClient(e error) ComputeClient {
149+
return computeErrorClient{e}
150+
}
151+
152+
func (e computeErrorClient) ListAvailabilityZones() ([]availabilityzones.AvailabilityZone, error) {
153+
return nil, e.error
154+
}
155+
156+
func (e computeErrorClient) GetFlavorIDFromName(flavor string) (string, error) {
157+
return "", e.error
158+
}
159+
160+
func (e computeErrorClient) CreateServer(createOpts servers.CreateOptsBuilder) (*ServerExt, error) {
161+
return nil, e.error
162+
}
163+
164+
func (e computeErrorClient) DeleteServer(serverID string) error {
165+
return e.error
166+
}
167+
168+
func (e computeErrorClient) GetServer(serverID string) (*ServerExt, error) {
169+
return nil, e.error
170+
}
171+
172+
func (e computeErrorClient) ListServers(listOpts servers.ListOptsBuilder) ([]ServerExt, error) {
173+
return nil, e.error
174+
}
175+
176+
func (e computeErrorClient) ListAttachedInterfaces(serverID string) ([]attachinterfaces.Interface, error) {
177+
return nil, e.error
178+
}
179+
180+
func (e computeErrorClient) DeleteAttachedInterface(serverID, portID string) error {
181+
return e.error
182+
}

pkg/clients/image.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package clients
18+
19+
import (
20+
"fmt"
21+
22+
"github.com/gophercloud/gophercloud"
23+
"github.com/gophercloud/gophercloud/openstack"
24+
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
25+
26+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/metrics"
27+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/scope"
28+
)
29+
30+
type ImageClient interface {
31+
ListImages(listOpts images.ListOptsBuilder) ([]images.Image, error)
32+
}
33+
34+
type imageClient struct{ client *gophercloud.ServiceClient }
35+
36+
// NewImageClient returns a new glance client.
37+
func NewImageClient(scope *scope.Scope) (ImageClient, error) {
38+
images, err := openstack.NewImageServiceV2(scope.ProviderClient, gophercloud.EndpointOpts{
39+
Region: scope.ProviderClientOpts.RegionName,
40+
})
41+
if err != nil {
42+
return nil, fmt.Errorf("failed to create image service client: %v", err)
43+
}
44+
45+
return imageClient{images}, nil
46+
}
47+
48+
func (c imageClient) ListImages(listOpts images.ListOptsBuilder) ([]images.Image, error) {
49+
mc := metrics.NewMetricPrometheusContext("image", "list")
50+
pages, err := images.List(c.client, listOpts).AllPages()
51+
if mc.ObserveRequest(err) != nil {
52+
return nil, err
53+
}
54+
return images.ExtractImages(pages)
55+
}
56+
57+
type imageErrorClient struct{ error }
58+
59+
// NewImageErrorClient returns an ImageClient in which every method returns the given error.
60+
func NewImageErrorClient(e error) ImageClient {
61+
return imageErrorClient{e}
62+
}
63+
64+
func (e imageErrorClient) ListImages(listOpts images.ListOptsBuilder) ([]images.Image, error) {
65+
return nil, e.error
66+
}

pkg/cloud/services/loadbalancer/client.go renamed to pkg/clients/loadbalancer.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package loadbalancer
17+
package clients
1818

1919
import (
2020
"fmt"
2121

2222
"github.com/gophercloud/gophercloud"
23+
"github.com/gophercloud/gophercloud/openstack"
2324
"github.com/gophercloud/gophercloud/openstack/compute/apiversions"
2425
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/listeners"
2526
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/loadbalancers"
@@ -28,6 +29,7 @@ import (
2829
"github.com/gophercloud/gophercloud/openstack/loadbalancer/v2/providers"
2930

3031
"sigs.k8s.io/cluster-api-provider-openstack/pkg/metrics"
32+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/scope"
3133
capoerrors "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/errors"
3234
)
3335

@@ -59,6 +61,18 @@ type lbClient struct {
5961
serviceClient *gophercloud.ServiceClient
6062
}
6163

64+
// NewLbClient returns a new loadbalancer client.
65+
func NewLbClient(scope *scope.Scope) (LbClient, error) {
66+
loadbalancerClient, err := openstack.NewLoadBalancerV2(scope.ProviderClient, gophercloud.EndpointOpts{
67+
Region: scope.ProviderClientOpts.RegionName,
68+
})
69+
if err != nil {
70+
return nil, fmt.Errorf("failed to create load balancer service client: %v", err)
71+
}
72+
73+
return &lbClient{loadbalancerClient}, nil
74+
}
75+
6276
func (l lbClient) CreateLoadBalancer(opts loadbalancers.CreateOptsBuilder) (*loadbalancers.LoadBalancer, error) {
6377
mc := metrics.NewMetricPrometheusContext("loadbalancer", "create")
6478
lb, err := loadbalancers.Create(l.serviceClient, opts).Extract()

0 commit comments

Comments
 (0)