Skip to content

Commit a954a7f

Browse files
committed
Port CloudProvider to use new SDK
1 parent d9a196c commit a954a7f

12 files changed

+1256
-819
lines changed

pkg/oci/ccm.go

+7-13
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ import (
2525
"github.com/golang/glog"
2626

2727
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
28-
"k8s.io/apimachinery/pkg/util/wait"
29-
"k8s.io/client-go/informers"
28+
wait "k8s.io/apimachinery/pkg/util/wait"
29+
informers "k8s.io/client-go/informers"
3030
clientset "k8s.io/client-go/kubernetes"
31-
"k8s.io/client-go/tools/cache"
32-
"k8s.io/kubernetes/pkg/cloudprovider"
33-
"k8s.io/kubernetes/pkg/controller"
31+
listersv1 "k8s.io/client-go/listers/core/v1"
32+
cache "k8s.io/client-go/tools/cache"
33+
cloudprovider "k8s.io/kubernetes/pkg/cloudprovider"
34+
controller "k8s.io/kubernetes/pkg/controller"
3435

3536
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/client"
3637
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/util"
37-
listersv1 "k8s.io/client-go/listers/core/v1"
3838
)
3939

4040
// ProviderName uniquely identifies the Oracle Bare Metal Cloud Services (OCI)
@@ -61,19 +61,13 @@ type CloudProvider struct {
6161
// interface.
6262
var _ cloudprovider.Interface = &CloudProvider{}
6363

64-
// NewCloudProvider creates a new baremetal.CloudProvider.
64+
// NewCloudProvider creates a new oci.CloudProvider.
6565
func NewCloudProvider(cfg *client.Config) (cloudprovider.Interface, error) {
6666
c, err := client.New(cfg)
6767
if err != nil {
6868
return nil, err
6969
}
7070

71-
err = c.Validate()
72-
if err != nil {
73-
glog.Errorf("cloudprovider.Validate() failed to communicate with OCI: %v", err)
74-
return nil, err
75-
}
76-
7771
return &CloudProvider{
7872
client: c,
7973
config: cfg,

pkg/oci/instances.go

+60-22
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,21 @@
1515
package oci
1616

1717
import (
18-
"errors"
18+
"context"
1919
"fmt"
20+
"net"
2021
"strings"
2122

2223
"github.com/golang/glog"
23-
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/client"
24-
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/util"
24+
"github.com/oracle/oci-go-sdk/core"
25+
"github.com/pkg/errors"
2526

2627
api "k8s.io/api/core/v1"
27-
"k8s.io/apimachinery/pkg/types"
28-
"k8s.io/kubernetes/pkg/cloudprovider"
28+
types "k8s.io/apimachinery/pkg/types"
29+
cloudprovider "k8s.io/kubernetes/pkg/cloudprovider"
30+
31+
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/client"
32+
"github.com/oracle/oci-cloud-controller-manager/pkg/oci/util"
2933
)
3034

3135
var _ cloudprovider.Instances = &CloudProvider{}
@@ -42,18 +46,48 @@ func mapInstanceNameToNodeName(displayName string) types.NodeName {
4246
return types.NodeName(strings.ToLower(displayName))
4347
}
4448

49+
func extractNodeAddressesFromVNIC(vnic *core.Vnic) ([]api.NodeAddress, error) {
50+
addresses := []api.NodeAddress{}
51+
if vnic == nil {
52+
return addresses, nil
53+
}
54+
55+
if vnic.PrivateIp != nil && *vnic.PrivateIp != "" {
56+
ip := net.ParseIP(*vnic.PrivateIp)
57+
if ip == nil {
58+
return nil, fmt.Errorf("instance has invalid private address: %q", *vnic.PrivateIp)
59+
}
60+
addresses = append(addresses, api.NodeAddress{Type: api.NodeInternalIP, Address: ip.String()})
61+
}
62+
63+
if vnic.PublicIp != nil && *vnic.PublicIp != "" {
64+
ip := net.ParseIP(*vnic.PublicIp)
65+
if ip == nil {
66+
return nil, errors.Errorf("instance has invalid public address: %q", *vnic.PublicIp)
67+
}
68+
addresses = append(addresses, api.NodeAddress{Type: api.NodeExternalIP, Address: ip.String()})
69+
}
70+
71+
return addresses, nil
72+
}
73+
4574
// NodeAddresses returns the addresses of the specified instance.
4675
// TODO(roberthbailey): This currently is only used in such a way that it
4776
// returns the address of the calling instance. We should do a rename to
4877
// make this clearer.
4978
func (cp *CloudProvider) NodeAddresses(name types.NodeName) ([]api.NodeAddress, error) {
5079
glog.V(4).Infof("NodeAddresses(%q) called", name)
5180

52-
inst, err := cp.client.GetInstanceByNodeName(mapNodeNameToInstanceName(name))
81+
inst, err := cp.client.Compute().GetInstanceByNodeName(context.TODO(), mapNodeNameToInstanceName(name))
5382
if err != nil {
54-
return nil, err
83+
return []api.NodeAddress{}, errors.Wrap(err, "GetInstanceByNodeName")
5584
}
56-
return cp.client.GetNodeAddressesForInstance(inst.ID)
85+
86+
vnic, err := cp.client.Compute().GetPrimaryVNICForInstance(context.TODO(), *inst.Id)
87+
if err != nil {
88+
return []api.NodeAddress{}, errors.Wrap(err, "GetPrimaryVNICForInstance")
89+
}
90+
return extractNodeAddressesFromVNIC(vnic)
5791
}
5892

5993
// NodeAddressesByProviderID returns the addresses of the specified instance.
@@ -64,7 +98,11 @@ func (cp *CloudProvider) NodeAddresses(name types.NodeName) ([]api.NodeAddress,
6498
func (cp *CloudProvider) NodeAddressesByProviderID(providerID string) ([]api.NodeAddress, error) {
6599
glog.V(4).Infof("NodeAddressesByProviderID(%q) called", providerID)
66100
instanceID := util.MapProviderIDToInstanceID(providerID)
67-
return cp.client.GetNodeAddressesForInstance(instanceID)
101+
vnic, err := cp.client.Compute().GetPrimaryVNICForInstance(context.TODO(), instanceID)
102+
if err != nil {
103+
return []api.NodeAddress{}, errors.Wrap(err, "GetPrimaryVNICForInstance")
104+
}
105+
return extractNodeAddressesFromVNIC(vnic)
68106
}
69107

70108
// ExternalID returns the cloud provider ID of the node with the specified NodeName.
@@ -74,7 +112,7 @@ func (cp *CloudProvider) ExternalID(nodeName types.NodeName) (string, error) {
74112
glog.V(4).Infof("ExternalID(%q) called", nodeName)
75113

76114
instName := mapNodeNameToInstanceName(nodeName)
77-
inst, err := cp.client.GetInstanceByNodeName(instName)
115+
inst, err := cp.client.Compute().GetInstanceByNodeName(context.TODO(), instName)
78116
if client.IsNotFound(err) {
79117
glog.Infof("Instance %q was not found. Unable to get ExternalID: %v", instName, err)
80118
return "", cloudprovider.InstanceNotFound
@@ -84,8 +122,8 @@ func (cp *CloudProvider) ExternalID(nodeName types.NodeName) (string, error) {
84122
return "", err
85123
}
86124

87-
glog.V(4).Infof("Got ExternalID %s for %s", inst.ID, nodeName)
88-
return inst.ID, nil
125+
glog.V(4).Infof("Got ExternalID %s for %s", *inst.Id, nodeName)
126+
return *inst.Id, nil
89127
}
90128

91129
// InstanceID returns the cloud provider ID of the node with the specified NodeName.
@@ -94,34 +132,34 @@ func (cp *CloudProvider) InstanceID(nodeName types.NodeName) (string, error) {
94132
glog.V(4).Infof("InstanceID(%q) called", nodeName)
95133

96134
name := mapNodeNameToInstanceName(nodeName)
97-
inst, err := cp.client.GetInstanceByNodeName(name)
135+
inst, err := cp.client.Compute().GetInstanceByNodeName(context.TODO(), name)
98136
if err != nil {
99-
return "", fmt.Errorf("unable to fetch InstanceID for %q: %v", name, err)
137+
return "", errors.Wrap(err, "GetInstanceByNodeName")
100138
}
101-
return inst.ID, nil
139+
return *inst.Id, nil
102140
}
103141

104142
// InstanceType returns the type of the specified instance.
105143
func (cp *CloudProvider) InstanceType(name types.NodeName) (string, error) {
106144
glog.V(4).Infof("InstanceType(%q) called", name)
107145

108-
inst, err := cp.client.GetInstanceByNodeName(mapNodeNameToInstanceName(name))
146+
inst, err := cp.client.Compute().GetInstanceByNodeName(context.TODO(), mapNodeNameToInstanceName(name))
109147
if err != nil {
110-
return "", fmt.Errorf("getInstanceByNodeName failed for %q with %v", name, err)
148+
return "", errors.Wrap(err, "GetInstanceByNodeName")
111149
}
112-
return inst.Shape, nil
150+
return *inst.Shape, nil
113151
}
114152

115153
// InstanceTypeByProviderID returns the type of the specified instance.
116154
func (cp *CloudProvider) InstanceTypeByProviderID(providerID string) (string, error) {
117155
glog.V(4).Infof("InstanceTypeByProviderID(%q) called", providerID)
118156

119157
instanceID := util.MapProviderIDToInstanceID(providerID)
120-
inst, err := cp.client.GetInstance(instanceID)
158+
inst, err := cp.client.Compute().GetInstance(context.TODO(), instanceID)
121159
if err != nil {
122-
return "", err
160+
return "", errors.Wrap(err, "GetInstance")
123161
}
124-
return inst.Shape, nil
162+
return *inst.Shape, nil
125163
}
126164

127165
// AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances
@@ -143,7 +181,7 @@ func (cp *CloudProvider) CurrentNodeName(hostname string) (types.NodeName, error
143181
func (cp *CloudProvider) InstanceExistsByProviderID(providerID string) (bool, error) {
144182
glog.V(4).Infof("InstanceExistsByProviderID(%q) called", providerID)
145183
instanceID := util.MapProviderIDToInstanceID(providerID)
146-
instance, err := cp.client.GetInstance(instanceID)
184+
instance, err := cp.client.Compute().GetInstance(context.TODO(), instanceID)
147185
if client.IsNotFound(err) {
148186
return false, nil
149187
}

pkg/oci/instances_test.go

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2018 Oracle and/or its affiliates. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package oci
16+
17+
import (
18+
"errors"
19+
"reflect"
20+
"testing"
21+
22+
"github.com/oracle/oci-go-sdk/common"
23+
"github.com/oracle/oci-go-sdk/core"
24+
25+
api "k8s.io/api/core/v1"
26+
)
27+
28+
func TestExtractNodeAddressesFromVNIC(t *testing.T) {
29+
testCases := []struct {
30+
name string
31+
in *core.Vnic
32+
out []api.NodeAddress
33+
err error
34+
}{
35+
{
36+
name: "basic-complete",
37+
in: &core.Vnic{
38+
PrivateIp: common.String("10.0.0.1"),
39+
PublicIp: common.String("0.0.0.1"),
40+
},
41+
out: []api.NodeAddress{
42+
api.NodeAddress{Type: api.NodeInternalIP, Address: "10.0.0.1"},
43+
api.NodeAddress{Type: api.NodeExternalIP, Address: "0.0.0.1"},
44+
},
45+
err: nil,
46+
},
47+
{
48+
name: "no-external-ip",
49+
in: &core.Vnic{
50+
PrivateIp: common.String("10.0.0.1"),
51+
},
52+
out: []api.NodeAddress{
53+
api.NodeAddress{Type: api.NodeInternalIP, Address: "10.0.0.1"},
54+
},
55+
err: nil,
56+
},
57+
{
58+
name: "no-internal-ip",
59+
in: &core.Vnic{
60+
PublicIp: common.String("0.0.0.1"),
61+
},
62+
out: []api.NodeAddress{
63+
api.NodeAddress{Type: api.NodeExternalIP, Address: "0.0.0.1"},
64+
},
65+
err: nil,
66+
},
67+
{
68+
name: "invalid-external-ip",
69+
in: &core.Vnic{
70+
PublicIp: common.String("0.0.0."),
71+
},
72+
out: nil,
73+
err: errors.New(`instance has invalid public address: "0.0.0."`),
74+
},
75+
{
76+
name: "invalid-external-ip",
77+
in: &core.Vnic{
78+
PrivateIp: common.String("10.0.0."),
79+
},
80+
out: nil,
81+
err: errors.New(`instance has invalid private address: "10.0.0."`),
82+
},
83+
}
84+
85+
for _, tt := range testCases {
86+
t.Run(tt.name, func(t *testing.T) {
87+
result, err := extractNodeAddressesFromVNIC(tt.in)
88+
if err != nil && err.Error() != tt.err.Error() {
89+
t.Errorf("extractNodeAddressesFromVNIC(%+v) got error %v, expected %v", tt.in, err, tt.err)
90+
}
91+
if !reflect.DeepEqual(result, tt.out) {
92+
t.Errorf("extractNodeAddressesFromVNIC(%+v) => %+v, want %+v", tt.in, result, tt.out)
93+
}
94+
})
95+
}
96+
}

0 commit comments

Comments
 (0)