Merge pull request #357 from krzysztof-jastrzebski/core-test
Cloudprovider/gce/gce_cloud_provider.go unit tests.
This commit is contained in:
commit
d3a924f04f
|
|
@ -58,7 +58,7 @@ func (b CloudProviderBuilder) Build(discoveryOpts cloudprovider.NodeGroupDiscove
|
||||||
|
|
||||||
if b.cloudProviderFlag == "gce" || b.cloudProviderFlag == "gke" {
|
if b.cloudProviderFlag == "gce" || b.cloudProviderFlag == "gke" {
|
||||||
// GCE Manager
|
// GCE Manager
|
||||||
var gceManager *gce.GceManager
|
var gceManager gce.GceManager
|
||||||
var gceError error
|
var gceError error
|
||||||
mode := gce.ModeGCE
|
mode := gce.ModeGCE
|
||||||
if b.cloudProviderFlag == "gke" {
|
if b.cloudProviderFlag == "gke" {
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,12 @@ var autoprovisionedMachineTypes = []string{
|
||||||
|
|
||||||
// GceCloudProvider implements CloudProvider interface.
|
// GceCloudProvider implements CloudProvider interface.
|
||||||
type GceCloudProvider struct {
|
type GceCloudProvider struct {
|
||||||
gceManager *GceManager
|
gceManager GceManager
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildGceCloudProvider builds CloudProvider implementation for GCE.
|
// BuildGceCloudProvider builds CloudProvider implementation for GCE.
|
||||||
func BuildGceCloudProvider(gceManager *GceManager, specs []string) (*GceCloudProvider, error) {
|
func BuildGceCloudProvider(gceManager GceManager, specs []string) (*GceCloudProvider, error) {
|
||||||
if gceManager.mode == ModeGKE && len(specs) != 0 {
|
if gceManager.getMode() == ModeGKE && len(specs) != 0 {
|
||||||
return nil, fmt.Errorf("GKE gets nodegroup specification via API, command line specs are not allowed")
|
return nil, fmt.Errorf("GKE gets nodegroup specification via API, command line specs are not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,8 +135,8 @@ func (gce *GceCloudProvider) NewNodeGroup(machineType string, labels map[string]
|
||||||
exist: false,
|
exist: false,
|
||||||
nodePoolName: nodePoolName,
|
nodePoolName: nodePoolName,
|
||||||
GceRef: GceRef{
|
GceRef: GceRef{
|
||||||
Project: gce.gceManager.projectId,
|
Project: gce.gceManager.getProjectId(),
|
||||||
Zone: gce.gceManager.zone,
|
Zone: gce.gceManager.getZone(),
|
||||||
Name: nodePoolName + "-temporary-mig",
|
Name: nodePoolName + "-temporary-mig",
|
||||||
},
|
},
|
||||||
minSize: minAutoprovisionedSize,
|
minSize: minAutoprovisionedSize,
|
||||||
|
|
@ -148,7 +148,7 @@ func (gce *GceCloudProvider) NewNodeGroup(machineType string, labels map[string]
|
||||||
},
|
},
|
||||||
gceManager: gce.gceManager,
|
gceManager: gce.gceManager,
|
||||||
}
|
}
|
||||||
_, err := gce.gceManager.templates.buildNodeFromAutoprovisioningSpec(mig)
|
_, err := gce.gceManager.getTemplates().buildNodeFromAutoprovisioningSpec(mig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +189,7 @@ type autoprovisioningSpec struct {
|
||||||
type Mig struct {
|
type Mig struct {
|
||||||
GceRef
|
GceRef
|
||||||
|
|
||||||
gceManager *GceManager
|
gceManager GceManager
|
||||||
minSize int
|
minSize int
|
||||||
maxSize int
|
maxSize int
|
||||||
autoprovisioned bool
|
autoprovisioned bool
|
||||||
|
|
@ -346,17 +346,17 @@ func (mig *Mig) Autoprovisioned() bool {
|
||||||
func (mig *Mig) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
func (mig *Mig) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
||||||
var node *apiv1.Node
|
var node *apiv1.Node
|
||||||
if mig.Exist() {
|
if mig.Exist() {
|
||||||
template, err := mig.gceManager.templates.getMigTemplate(mig)
|
template, err := mig.gceManager.getTemplates().getMigTemplate(mig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
node, err = mig.gceManager.templates.buildNodeFromTemplate(mig, template)
|
node, err = mig.gceManager.getTemplates().buildNodeFromTemplate(mig, template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if mig.Autoprovisioned() {
|
} else if mig.Autoprovisioned() {
|
||||||
var err error
|
var err error
|
||||||
node, err = mig.gceManager.templates.buildNodeFromAutoprovisioningSpec(mig)
|
node, err = mig.gceManager.getTemplates().buildNodeFromAutoprovisioningSpec(mig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +368,7 @@ func (mig *Mig) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
||||||
return nodeInfo, nil
|
return nodeInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildMig(value string, gceManager *GceManager) (*Mig, error) {
|
func buildMig(value string, gceManager GceManager) (*Mig, error) {
|
||||||
spec, err := dynamic.SpecFromString(value, true)
|
spec, err := dynamic.SpecFromString(value, true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,479 @@ limitations under the License.
|
||||||
package gce
|
package gce
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
apiv1 "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
|
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
|
||||||
|
. "k8s.io/autoscaler/cluster-autoscaler/utils/test"
|
||||||
|
|
||||||
|
apiv1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
gcev1 "google.golang.org/api/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type gceManagerMock struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) RegisterMig(mig *Mig) bool {
|
||||||
|
args := m.Called(mig)
|
||||||
|
return args.Bool(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) UnregisterMig(toBeRemoved *Mig) bool {
|
||||||
|
args := m.Called(toBeRemoved)
|
||||||
|
return args.Bool(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) GetMigSize(mig *Mig) (int64, error) {
|
||||||
|
args := m.Called(mig)
|
||||||
|
return args.Get(0).(int64), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) SetMigSize(mig *Mig, size int64) error {
|
||||||
|
args := m.Called(mig, size)
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) DeleteInstances(instances []*GceRef) error {
|
||||||
|
args := m.Called(instances)
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) GetMigForInstance(instance *GceRef) (*Mig, error) {
|
||||||
|
args := m.Called(instance)
|
||||||
|
return args.Get(0).(*Mig), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) GetMigNodes(mig *Mig) ([]string, error) {
|
||||||
|
args := m.Called(mig)
|
||||||
|
return args.Get(0).([]string), args.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) getMigs() []*migInformation {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).([]*migInformation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) createNodePool(mig *Mig) error {
|
||||||
|
args := m.Called(mig)
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) deleteNodePool(toBeRemoved *Mig) error {
|
||||||
|
args := m.Called(toBeRemoved)
|
||||||
|
return args.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) getZone() string {
|
||||||
|
args := m.Called()
|
||||||
|
return args.String(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) getProjectId() string {
|
||||||
|
args := m.Called()
|
||||||
|
return args.String(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) getMode() GcpCloudProviderMode {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(GcpCloudProviderMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerMock) getTemplates() *templateBuilder {
|
||||||
|
args := m.Called()
|
||||||
|
return args.Get(0).(*templateBuilder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildGceCloudProvider(t *testing.T) {
|
||||||
|
gceManagerMock := &gceManagerMock{}
|
||||||
|
|
||||||
|
ng1Name := "https://content.googleapis.com/compute/v1/projects/project1/zones/us-central1-b/instanceGroups/ng1"
|
||||||
|
ng2Name := "https://content.googleapis.com/compute/v1/projects/project1/zones/us-central1-b/instanceGroups/ng2"
|
||||||
|
|
||||||
|
// GCE mode.
|
||||||
|
gceManagerMock.On("getMode").Return(ModeGCE).Once()
|
||||||
|
gceManagerMock.On("RegisterMig",
|
||||||
|
mock.MatchedBy(func(mig *Mig) bool {
|
||||||
|
return mig.Name == "ng1" || mig.Name == "ng2"
|
||||||
|
})).Return(true).Times(2)
|
||||||
|
|
||||||
|
provider, err := BuildGceCloudProvider(gceManagerMock,
|
||||||
|
[]string{"0:10:" + ng1Name, "0:5:https:" + ng2Name})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, provider)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// GKE mode.
|
||||||
|
gceManagerMock.On("getMode").Return(ModeGKE).Once()
|
||||||
|
|
||||||
|
provider, err = BuildGceCloudProvider(gceManagerMock, []string{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, provider)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Error on GKE mode with specs.
|
||||||
|
gceManagerMock.On("getMode").Return(ModeGKE).Once()
|
||||||
|
|
||||||
|
provider, err = BuildGceCloudProvider(gceManagerMock,
|
||||||
|
[]string{"0:10:" + ng1Name, "0:5:https:" + ng2Name})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "GKE gets nodegroup specification via API, command line specs are not allowed", err.Error())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeGroups(t *testing.T) {
|
||||||
|
gceManagerMock := &gceManagerMock{}
|
||||||
|
gce := &GceCloudProvider{
|
||||||
|
gceManager: gceManagerMock,
|
||||||
|
}
|
||||||
|
mig := &migInformation{config: &Mig{GceRef: GceRef{Name: "ng1"}}}
|
||||||
|
gceManagerMock.On("getMigs").Return([]*migInformation{mig}).Once()
|
||||||
|
result := gce.NodeGroups()
|
||||||
|
assert.Equal(t, []cloudprovider.NodeGroup{mig.config}, result)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeGroupForNode(t *testing.T) {
|
||||||
|
gceManagerMock := &gceManagerMock{}
|
||||||
|
gce := &GceCloudProvider{
|
||||||
|
gceManager: gceManagerMock,
|
||||||
|
}
|
||||||
|
n := BuildTestNode("n1", 1000, 1000)
|
||||||
|
n.Spec.ProviderID = "gce://project1/us-central1-b/n1"
|
||||||
|
mig := Mig{GceRef: GceRef{Name: "ng1"}}
|
||||||
|
gceManagerMock.On("GetMigForInstance", mock.AnythingOfType("*gce.GceRef")).Return(&mig, nil).Once()
|
||||||
|
|
||||||
|
nodeGroup, err := gce.NodeGroupForNode(n)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, mig, *reflect.ValueOf(nodeGroup).Interface().(*Mig))
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMachineTypeResponse = `{
|
||||||
|
"kind": "compute#machineType",
|
||||||
|
"id": "3001",
|
||||||
|
"creationTimestamp": "2015-01-16T09:25:43.314-08:00",
|
||||||
|
"name": "n1-standard-1",
|
||||||
|
"description": "1 vCPU, 3.75 GB RAM",
|
||||||
|
"guestCpus": 1,
|
||||||
|
"memoryMb": 3840,
|
||||||
|
"maximumPersistentDisks": 32,
|
||||||
|
"maximumPersistentDisksSizeGb": "65536",
|
||||||
|
"zone": "us-central1-a",
|
||||||
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/krzysztof-jastrzebski-dev/zones/us-central1-a/machineTypes/n1-standard-1",
|
||||||
|
"isSharedCpu": false
|
||||||
|
}`
|
||||||
|
|
||||||
|
const getInstanceGroupManagerResponse = `{
|
||||||
|
"kind": "compute#instanceGroupManager",
|
||||||
|
"id": "3213213219",
|
||||||
|
"creationTimestamp": "2017-09-15T04:47:24.687-07:00",
|
||||||
|
"name": "gke-cluster-1-default-pool",
|
||||||
|
"zone": "https://www.googleapis.com/compute/v1/projects/project1/zones/us-central1-b",
|
||||||
|
"instanceTemplate": "https://www.googleapis.com/compute/v1/projects/project1/global/instanceTemplates/gke-cluster-1-default-pool",
|
||||||
|
"instanceGroup": "https://www.googleapis.com/compute/v1/projects/project1/zones/us-central1-b/instanceGroups/gke-cluster-1-default-pool",
|
||||||
|
"baseInstanceName": "gke-cluster-1-default-pool-f23aac-grp",
|
||||||
|
"fingerprint": "kfdsuH",
|
||||||
|
"currentActions": {
|
||||||
|
"none": 3,
|
||||||
|
"creating": 0,
|
||||||
|
"creatingWithoutRetries": 0,
|
||||||
|
"recreating": 0,
|
||||||
|
"deleting": 0,
|
||||||
|
"abandoning": 0,
|
||||||
|
"restarting": 0,
|
||||||
|
"refreshing": 0
|
||||||
|
},
|
||||||
|
"targetSize": 3,
|
||||||
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/project1/zones/us-central1-b/instanceGroupManagers/gke-cluster-1-default-pool"
|
||||||
|
}`
|
||||||
|
|
||||||
|
const getInstanceTemplateResponse = `{
|
||||||
|
"kind": "compute#instanceTemplate",
|
||||||
|
"id": "28701103232323232",
|
||||||
|
"creationTimestamp": "2017-09-15T04:47:21.577-07:00",
|
||||||
|
"name": "gke-cluster-1-default-pool",
|
||||||
|
"description": "",
|
||||||
|
"properties": {
|
||||||
|
"tags": {
|
||||||
|
"items": [
|
||||||
|
"gke-cluster-1-fc0afeeb-node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"machineType": "n1-standard-1",
|
||||||
|
"canIpForward": true,
|
||||||
|
"networkInterfaces": [
|
||||||
|
{
|
||||||
|
"kind": "compute#networkInterface",
|
||||||
|
"network": "https://www.googleapis.com/compute/v1/projects/project1/global/networks/default",
|
||||||
|
"subnetwork": "https://www.googleapis.com/compute/v1/projects/project1/regions/us-central1/subnetworks/default",
|
||||||
|
"accessConfigs": [
|
||||||
|
{
|
||||||
|
"kind": "compute#accessConfig",
|
||||||
|
"type": "ONE_TO_ONE_NAT",
|
||||||
|
"name": "external-nat"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"disks": [
|
||||||
|
{
|
||||||
|
"kind": "compute#attachedDisk",
|
||||||
|
"type": "PERSISTENT",
|
||||||
|
"mode": "READ_WRITE",
|
||||||
|
"boot": true,
|
||||||
|
"initializeParams": {
|
||||||
|
"sourceImage": "https://www.googleapis.com/compute/v1/projects/gke-node-images/global/images/cos-stable-60-9592-84-0",
|
||||||
|
"diskSizeGb": "100",
|
||||||
|
"diskType": "pd-standard"
|
||||||
|
},
|
||||||
|
"autoDelete": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kind": "compute#metadata",
|
||||||
|
"fingerprint": "F7n_RsHD3ng=",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"key": "kube-env",
|
||||||
|
"value": "ALLOCATE_NODE_CIDRS: \"true\"\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "user-data",
|
||||||
|
"value": "#cloud-config\n\nwrite_files:\n - path: /etc/systemd/system/kube-node-installation.service\n "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "gci-update-strategy",
|
||||||
|
"value": "update_disabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "gci-ensure-gke-docker",
|
||||||
|
"value": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "configure-sh",
|
||||||
|
"value": "#!/bin/bash\n\n# Copyright 2016 The Kubernetes Authors.\n#\n# Licensed under the Apache License, "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "cluster-name",
|
||||||
|
"value": "cluster-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"serviceAccounts": [
|
||||||
|
{
|
||||||
|
"email": "default",
|
||||||
|
"scopes": [
|
||||||
|
"https://www.googleapis.com/auth/compute",
|
||||||
|
"https://www.googleapis.com/auth/devstorage.read_only",
|
||||||
|
"https://www.googleapis.com/auth/logging.write",
|
||||||
|
"https://www.googleapis.com/auth/monitoring.write",
|
||||||
|
"https://www.googleapis.com/auth/servicecontrol",
|
||||||
|
"https://www.googleapis.com/auth/service.management.readonly",
|
||||||
|
"https://www.googleapis.com/auth/trace.append"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scheduling": {
|
||||||
|
"onHostMaintenance": "MIGRATE",
|
||||||
|
"automaticRestart": true,
|
||||||
|
"preemptible": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selfLink": "https://www.googleapis.com/compute/v1/projects/project1/global/instanceTemplates/gke-cluster-1-default-pool-f7607aac"
|
||||||
|
}`
|
||||||
|
|
||||||
|
func TestMig(t *testing.T) {
|
||||||
|
server := NewHttpServerMock()
|
||||||
|
defer server.Close()
|
||||||
|
gceManagerMock := &gceManagerMock{}
|
||||||
|
client := &http.Client{}
|
||||||
|
gceService, err := gcev1.New(client)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
gceService.BasePath = server.URL
|
||||||
|
templateBuilder := &templateBuilder{gceService, "us-central1-b", "project1"}
|
||||||
|
gce := &GceCloudProvider{
|
||||||
|
gceManager: gceManagerMock,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test NewNodeGroup.
|
||||||
|
gceManagerMock.On("getProjectId").Return("project1").Once()
|
||||||
|
gceManagerMock.On("getZone").Return("us-central1-b").Once()
|
||||||
|
gceManagerMock.On("getTemplates").Return(templateBuilder).Once()
|
||||||
|
server.On("handle", "/project1/zones/us-central1-b/machineTypes/n1-standard-1").Return(getMachineTypeResponse).Once()
|
||||||
|
nodeGroup, err := gce.NewNodeGroup("n1-standard-1", nil, nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, nodeGroup)
|
||||||
|
mig1 := reflect.ValueOf(nodeGroup).Interface().(*Mig)
|
||||||
|
assert.True(t, strings.HasPrefix(mig1.Id(), "https://content.googleapis.com/compute/v1/projects/project1/zones/us-central1-b/instanceGroups/nodeautoprovisioning-n1-standard-1"))
|
||||||
|
assert.Equal(t, true, mig1.Autoprovisioned())
|
||||||
|
assert.Equal(t, 0, mig1.MinSize())
|
||||||
|
assert.Equal(t, 1000, mig1.MaxSize())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test TargetSize.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(2), nil).Once()
|
||||||
|
targetSize, err := mig1.TargetSize()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 2, targetSize)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test IncreaseSize.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(2), nil).Once()
|
||||||
|
gceManagerMock.On("SetMigSize", mock.AnythingOfType("*gce.Mig"), int64(3)).Return(nil).Once()
|
||||||
|
err = mig1.IncreaseSize(1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test IncreaseSize - fail on wrong size.
|
||||||
|
err = mig1.IncreaseSize(0)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "size increase must be positive", err.Error())
|
||||||
|
|
||||||
|
// Test IncreaseSize - fail on too big delta.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(2), nil).Once()
|
||||||
|
err = mig1.IncreaseSize(1000)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "size increase too large - desired:1002 max:1000", err.Error())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test DecreaseTargetSize.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(3), nil).Once()
|
||||||
|
gceManagerMock.On("GetMigNodes", mock.AnythingOfType("*gce.Mig")).Return(
|
||||||
|
[]string{"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-9j4g",
|
||||||
|
"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1"}, nil).Once()
|
||||||
|
gceManagerMock.On("SetMigSize", mock.AnythingOfType("*gce.Mig"), int64(2)).Return(nil).Once()
|
||||||
|
err = mig1.DecreaseTargetSize(-1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test DecreaseTargetSize - fail on positive delta.
|
||||||
|
err = mig1.DecreaseTargetSize(1)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "size decrease must be negative", err.Error())
|
||||||
|
|
||||||
|
// Test DecreaseTargetSize - fail on deleting existing nodes.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(3), nil).Once()
|
||||||
|
gceManagerMock.On("GetMigNodes", mock.AnythingOfType("*gce.Mig")).Return(
|
||||||
|
[]string{"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-9j4g",
|
||||||
|
"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1"}, nil).Once()
|
||||||
|
|
||||||
|
err = mig1.DecreaseTargetSize(-2)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "attempt to delete existing nodes targetSize:3 delta:-2 existingNodes: 2", err.Error())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test Belongs - true.
|
||||||
|
gceManagerMock.On("GetMigForInstance", mock.AnythingOfType("*gce.GceRef")).Return(mig1, nil).Once()
|
||||||
|
node := BuildTestNode("gke-cluster-1-default-pool-f7607aac-dck1", 1000, 1000)
|
||||||
|
node.Spec.ProviderID = "gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1"
|
||||||
|
|
||||||
|
belongs, err := mig1.Belongs(node)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, belongs)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test Belongs - false.
|
||||||
|
mig2 := &Mig{
|
||||||
|
GceRef: GceRef{
|
||||||
|
Project: "project1",
|
||||||
|
Zone: "us-central1-b",
|
||||||
|
Name: "default-pool",
|
||||||
|
},
|
||||||
|
gceManager: gceManagerMock,
|
||||||
|
minSize: 0,
|
||||||
|
maxSize: 1000,
|
||||||
|
autoprovisioned: true,
|
||||||
|
exist: true,
|
||||||
|
nodePoolName: "default-pool",
|
||||||
|
spec: nil}
|
||||||
|
gceManagerMock.On("GetMigForInstance", mock.AnythingOfType("*gce.GceRef")).Return(mig2, nil).Once()
|
||||||
|
|
||||||
|
belongs, err = mig1.Belongs(node)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.False(t, belongs)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test DeleteNodes.
|
||||||
|
n1 := BuildTestNode("gke-cluster-1-default-pool-f7607aac-9j4g", 1000, 1000)
|
||||||
|
n1.Spec.ProviderID = "gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-9j4g"
|
||||||
|
n1ref := &GceRef{"project1", "us-central1-b", "gke-cluster-1-default-pool-f7607aac-9j4g"}
|
||||||
|
n2 := BuildTestNode("gke-cluster-1-default-pool-f7607aac-dck1", 1000, 1000)
|
||||||
|
n2.Spec.ProviderID = "gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1"
|
||||||
|
n2ref := &GceRef{"project1", "us-central1-b", "gke-cluster-1-default-pool-f7607aac-dck1"}
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(2), nil).Once()
|
||||||
|
gceManagerMock.On("GetMigForInstance", n1ref).Return(mig1, nil).Once()
|
||||||
|
gceManagerMock.On("GetMigForInstance", n2ref).Return(mig1, nil).Once()
|
||||||
|
gceManagerMock.On("DeleteInstances", []*GceRef{n1ref, n2ref}).Return(nil).Once()
|
||||||
|
err = mig1.DeleteNodes([]*apiv1.Node{n1, n2})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test DeleteNodes - fail on reaching min size.
|
||||||
|
gceManagerMock.On("GetMigSize", mock.AnythingOfType("*gce.Mig")).Return(int64(0), nil).Once()
|
||||||
|
err = mig1.DeleteNodes([]*apiv1.Node{n1, n2})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "min size reached, nodes will not be deleted", err.Error())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test Nodes.
|
||||||
|
gceManagerMock.On("GetMigNodes", mock.AnythingOfType("*gce.Mig")).Return(
|
||||||
|
[]string{"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-9j4g",
|
||||||
|
"gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1"}, nil).Once()
|
||||||
|
nodes, err := mig1.Nodes()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-9j4g", nodes[0])
|
||||||
|
assert.Equal(t, "gce://project1/us-central1-b/gke-cluster-1-default-pool-f7607aac-dck1", nodes[1])
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test Create.
|
||||||
|
gceManagerMock.On("createNodePool", mock.AnythingOfType("*gce.Mig")).Return(nil).Once()
|
||||||
|
err = mig1.Create()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test Delete.
|
||||||
|
mig1.exist = true
|
||||||
|
gceManagerMock.On("deleteNodePool", mock.AnythingOfType("*gce.Mig")).Return(nil).Once()
|
||||||
|
err = mig1.Delete()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test TemplateNodeInfo.
|
||||||
|
gceManagerMock.On("getTemplates").Return(templateBuilder).Times(2)
|
||||||
|
server.On("handle", "/project1/zones/us-central1-b/instanceGroupManagers/default-pool").Return(getInstanceGroupManagerResponse).Once()
|
||||||
|
server.On("handle", "/project1/global/instanceTemplates/gke-cluster-1-default-pool").Return(getInstanceTemplateResponse).Once()
|
||||||
|
server.On("handle", "/project1/zones/us-central1-b/machineTypes/n1-standard-1").Return(getMachineTypeResponse).Once()
|
||||||
|
templateNodeInfo, err := mig2.TemplateNodeInfo()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, templateNodeInfo)
|
||||||
|
assert.NotNil(t, templateNodeInfo.Node())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
|
||||||
|
// Test TemplateNodeInfo for non-existing autoprovisioned Mig.
|
||||||
|
gceManagerMock.On("getTemplates").Return(templateBuilder).Once()
|
||||||
|
server.On("handle", "/project1/zones/us-central1-b/machineTypes/n1-standard-1").Return(getMachineTypeResponse).Once()
|
||||||
|
mig1.exist = false
|
||||||
|
templateNodeInfo, err = mig1.TemplateNodeInfo()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, templateNodeInfo)
|
||||||
|
assert.NotNil(t, templateNodeInfo.Node())
|
||||||
|
mock.AssertExpectationsForObjects(t, gceManagerMock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGceRefFromProviderId(t *testing.T) {
|
||||||
|
ref, err := GceRefFromProviderId("gce://project1/us-central1-b/name1")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, GceRef{"project1", "us-central1-b", "name1"}, *ref)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildMig(t *testing.T) {
|
func TestBuildMig(t *testing.T) {
|
||||||
_, err := buildMig("a", nil)
|
_, err := buildMig("a", nil)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,33 @@ type migInformation struct {
|
||||||
basename string
|
basename string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GceManager is handles gce communication and data caching.
|
// GceManager handles gce communication and data caching.
|
||||||
type GceManager struct {
|
type GceManager interface {
|
||||||
|
// RegisterMig registers mig in Gce Manager. Returns true if the node group didn't exist before.
|
||||||
|
RegisterMig(mig *Mig) bool
|
||||||
|
// UnregisterMig unregisters mig in Gce Manager. Returns true if the node group has been removed.
|
||||||
|
UnregisterMig(toBeRemoved *Mig) bool
|
||||||
|
// GetMigSize gets MIG size.
|
||||||
|
GetMigSize(mig *Mig) (int64, error)
|
||||||
|
// SetMigSize sets MIG size.
|
||||||
|
SetMigSize(mig *Mig, size int64) error
|
||||||
|
// DeleteInstances deletes the given instances. All instances must be controlled by the same MIG.
|
||||||
|
DeleteInstances(instances []*GceRef) error
|
||||||
|
// GetMigForInstance returns MigConfig of the given Instance
|
||||||
|
GetMigForInstance(instance *GceRef) (*Mig, error)
|
||||||
|
// GetMigNodes returns mig nodes.
|
||||||
|
GetMigNodes(mig *Mig) ([]string, error)
|
||||||
|
getMigs() []*migInformation
|
||||||
|
createNodePool(mig *Mig) error
|
||||||
|
deleteNodePool(toBeRemoved *Mig) error
|
||||||
|
getZone() string
|
||||||
|
getProjectId() string
|
||||||
|
getMode() GcpCloudProviderMode
|
||||||
|
getTemplates() *templateBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
// gceManagerImpl handles gce communication and data caching.
|
||||||
|
type gceManagerImpl struct {
|
||||||
migs []*migInformation
|
migs []*migInformation
|
||||||
migCache map[GceRef]*Mig
|
migCache map[GceRef]*Mig
|
||||||
|
|
||||||
|
|
@ -85,7 +110,7 @@ type GceManager struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateGceManager constructs gceManager object.
|
// CreateGceManager constructs gceManager object.
|
||||||
func CreateGceManager(configReader io.Reader, mode GcpCloudProviderMode, clusterName string) (*GceManager, error) {
|
func CreateGceManager(configReader io.Reader, mode GcpCloudProviderMode, clusterName string) (GceManager, error) {
|
||||||
// Create Google Compute Engine token.
|
// Create Google Compute Engine token.
|
||||||
var err error
|
var err error
|
||||||
tokenSource := google.ComputeTokenSource("")
|
tokenSource := google.ComputeTokenSource("")
|
||||||
|
|
@ -127,7 +152,7 @@ func CreateGceManager(configReader io.Reader, mode GcpCloudProviderMode, cluster
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
manager := &GceManager{
|
manager := &gceManagerImpl{
|
||||||
migs: make([]*migInformation, 0),
|
migs: make([]*migInformation, 0),
|
||||||
gceService: gceService,
|
gceService: gceService,
|
||||||
migCache: make(map[GceRef]*Mig),
|
migCache: make(map[GceRef]*Mig),
|
||||||
|
|
@ -166,14 +191,14 @@ func CreateGceManager(configReader io.Reader, mode GcpCloudProviderMode, cluster
|
||||||
return manager, nil
|
return manager, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GceManager) assertGKE() {
|
func (m *gceManagerImpl) assertGKE() {
|
||||||
if m.mode != ModeGKE {
|
if m.mode != ModeGKE {
|
||||||
glog.Fatalf("This should run only in GKE mode")
|
glog.Fatalf("This should run only in GKE mode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets all registered node pools
|
// Gets all registered node pools
|
||||||
func (m *GceManager) fetchAllNodePools() error {
|
func (m *gceManagerImpl) fetchAllNodePools() error {
|
||||||
m.assertGKE()
|
m.assertGKE()
|
||||||
|
|
||||||
nodePoolsResponse, err := m.gkeService.Projects.Zones.Clusters.NodePools.List(m.projectId, m.zone, m.clusterName).Do()
|
nodePoolsResponse, err := m.gkeService.Projects.Zones.Clusters.NodePools.List(m.projectId, m.zone, m.clusterName).Do()
|
||||||
|
|
@ -228,7 +253,7 @@ func (m *GceManager) fetchAllNodePools() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterMig registers mig in Gce Manager. Returns true if the node group didn't exist before.
|
// RegisterMig registers mig in Gce Manager. Returns true if the node group didn't exist before.
|
||||||
func (m *GceManager) RegisterMig(mig *Mig) bool {
|
func (m *gceManagerImpl) RegisterMig(mig *Mig) bool {
|
||||||
m.migsMutex.Lock()
|
m.migsMutex.Lock()
|
||||||
defer m.migsMutex.Unlock()
|
defer m.migsMutex.Unlock()
|
||||||
|
|
||||||
|
|
@ -261,7 +286,7 @@ func (m *GceManager) RegisterMig(mig *Mig) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnregisterMig unregisters mig in Gce Manager. Returns true if the node group has been removed.
|
// UnregisterMig unregisters mig in Gce Manager. Returns true if the node group has been removed.
|
||||||
func (m *GceManager) UnregisterMig(toBeRemoved *Mig) bool {
|
func (m *gceManagerImpl) UnregisterMig(toBeRemoved *Mig) bool {
|
||||||
m.migsMutex.Lock()
|
m.migsMutex.Lock()
|
||||||
defer m.migsMutex.Unlock()
|
defer m.migsMutex.Unlock()
|
||||||
|
|
||||||
|
|
@ -280,7 +305,7 @@ func (m *GceManager) UnregisterMig(toBeRemoved *Mig) bool {
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GceManager) deleteNodePool(toBeRemoved *Mig) error {
|
func (m *gceManagerImpl) deleteNodePool(toBeRemoved *Mig) error {
|
||||||
m.assertGKE()
|
m.assertGKE()
|
||||||
if !toBeRemoved.Autoprovisioned() {
|
if !toBeRemoved.Autoprovisioned() {
|
||||||
return fmt.Errorf("only autoprovisioned node pools can be deleted")
|
return fmt.Errorf("only autoprovisioned node pools can be deleted")
|
||||||
|
|
@ -298,7 +323,7 @@ func (m *GceManager) deleteNodePool(toBeRemoved *Mig) error {
|
||||||
return m.fetchAllNodePools()
|
return m.fetchAllNodePools()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GceManager) createNodePool(mig *Mig) error {
|
func (m *gceManagerImpl) createNodePool(mig *Mig) error {
|
||||||
m.assertGKE()
|
m.assertGKE()
|
||||||
|
|
||||||
// TODO: handle preemptable
|
// TODO: handle preemptable
|
||||||
|
|
@ -342,7 +367,7 @@ func (m *GceManager) createNodePool(mig *Mig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMigSize gets MIG size.
|
// GetMigSize gets MIG size.
|
||||||
func (m *GceManager) GetMigSize(mig *Mig) (int64, error) {
|
func (m *gceManagerImpl) GetMigSize(mig *Mig) (int64, error) {
|
||||||
igm, err := m.gceService.InstanceGroupManagers.Get(mig.Project, mig.Zone, mig.Name).Do()
|
igm, err := m.gceService.InstanceGroupManagers.Get(mig.Project, mig.Zone, mig.Name).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
|
|
@ -351,7 +376,7 @@ func (m *GceManager) GetMigSize(mig *Mig) (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMigSize sets MIG size.
|
// SetMigSize sets MIG size.
|
||||||
func (m *GceManager) SetMigSize(mig *Mig, size int64) error {
|
func (m *gceManagerImpl) SetMigSize(mig *Mig, size int64) error {
|
||||||
glog.V(0).Infof("Setting mig size %s to %d", mig.Id(), size)
|
glog.V(0).Infof("Setting mig size %s to %d", mig.Id(), size)
|
||||||
op, err := m.gceService.InstanceGroupManagers.Resize(mig.Project, mig.Zone, mig.Name, size).Do()
|
op, err := m.gceService.InstanceGroupManagers.Resize(mig.Project, mig.Zone, mig.Name, size).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -361,7 +386,7 @@ func (m *GceManager) SetMigSize(mig *Mig, size int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GCE
|
// GCE
|
||||||
func (m *GceManager) waitForOp(operation *gce.Operation, project string, zone string) error {
|
func (m *gceManagerImpl) waitForOp(operation *gce.Operation, project string, zone string) error {
|
||||||
for start := time.Now(); time.Since(start) < operationWaitTimeout; time.Sleep(operationPollInterval) {
|
for start := time.Now(); time.Since(start) < operationWaitTimeout; time.Sleep(operationPollInterval) {
|
||||||
glog.V(4).Infof("Waiting for operation %s %s %s", project, zone, operation.Name)
|
glog.V(4).Infof("Waiting for operation %s %s %s", project, zone, operation.Name)
|
||||||
if op, err := m.gceService.ZoneOperations.Get(project, zone, operation.Name).Do(); err == nil {
|
if op, err := m.gceService.ZoneOperations.Get(project, zone, operation.Name).Do(); err == nil {
|
||||||
|
|
@ -377,7 +402,7 @@ func (m *GceManager) waitForOp(operation *gce.Operation, project string, zone st
|
||||||
}
|
}
|
||||||
|
|
||||||
// GKE
|
// GKE
|
||||||
func (m *GceManager) waitForGkeOp(operation *gke.Operation) error {
|
func (m *gceManagerImpl) waitForGkeOp(operation *gke.Operation) error {
|
||||||
for start := time.Now(); time.Since(start) < operationWaitTimeout; time.Sleep(operationPollInterval) {
|
for start := time.Now(); time.Since(start) < operationWaitTimeout; time.Sleep(operationPollInterval) {
|
||||||
glog.V(4).Infof("Waiting for operation %s %s %s", m.projectId, m.zone, operation.Name)
|
glog.V(4).Infof("Waiting for operation %s %s %s", m.projectId, m.zone, operation.Name)
|
||||||
if op, err := m.gkeService.Projects.Zones.Operations.Get(m.projectId, m.zone, operation.Name).Do(); err == nil {
|
if op, err := m.gkeService.Projects.Zones.Operations.Get(m.projectId, m.zone, operation.Name).Do(); err == nil {
|
||||||
|
|
@ -393,7 +418,7 @@ func (m *GceManager) waitForGkeOp(operation *gke.Operation) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteInstances deletes the given instances. All instances must be controlled by the same MIG.
|
// DeleteInstances deletes the given instances. All instances must be controlled by the same MIG.
|
||||||
func (m *GceManager) DeleteInstances(instances []*GceRef) error {
|
func (m *gceManagerImpl) DeleteInstances(instances []*GceRef) error {
|
||||||
if len(instances) == 0 {
|
if len(instances) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +450,7 @@ func (m *GceManager) DeleteInstances(instances []*GceRef) error {
|
||||||
return m.waitForOp(op, commonMig.Project, commonMig.Zone)
|
return m.waitForOp(op, commonMig.Project, commonMig.Zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GceManager) getMigs() []*migInformation {
|
func (m *gceManagerImpl) getMigs() []*migInformation {
|
||||||
m.migsMutex.Lock()
|
m.migsMutex.Lock()
|
||||||
defer m.migsMutex.Unlock()
|
defer m.migsMutex.Unlock()
|
||||||
migs := make([]*migInformation, 0, len(m.migs))
|
migs := make([]*migInformation, 0, len(m.migs))
|
||||||
|
|
@ -437,8 +462,7 @@ func (m *GceManager) getMigs() []*migInformation {
|
||||||
}
|
}
|
||||||
return migs
|
return migs
|
||||||
}
|
}
|
||||||
|
func (m *gceManagerImpl) updateMigBasename(ref GceRef, basename string) {
|
||||||
func (m *GceManager) updateMigBasename(ref GceRef, basename string) {
|
|
||||||
m.migsMutex.Lock()
|
m.migsMutex.Lock()
|
||||||
defer m.migsMutex.Unlock()
|
defer m.migsMutex.Unlock()
|
||||||
for _, mig := range m.migs {
|
for _, mig := range m.migs {
|
||||||
|
|
@ -449,7 +473,7 @@ func (m *GceManager) updateMigBasename(ref GceRef, basename string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMigForInstance returns MigConfig of the given Instance
|
// GetMigForInstance returns MigConfig of the given Instance
|
||||||
func (m *GceManager) GetMigForInstance(instance *GceRef) (*Mig, error) {
|
func (m *gceManagerImpl) GetMigForInstance(instance *GceRef) (*Mig, error) {
|
||||||
m.cacheMutex.Lock()
|
m.cacheMutex.Lock()
|
||||||
defer m.cacheMutex.Unlock()
|
defer m.cacheMutex.Unlock()
|
||||||
if mig, found := m.migCache[*instance]; found {
|
if mig, found := m.migCache[*instance]; found {
|
||||||
|
|
@ -473,7 +497,7 @@ func (m *GceManager) GetMigForInstance(instance *GceRef) (*Mig, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GceManager) regenerateCache() error {
|
func (m *gceManagerImpl) regenerateCache() error {
|
||||||
newMigCache := make(map[GceRef]*Mig)
|
newMigCache := make(map[GceRef]*Mig)
|
||||||
|
|
||||||
for _, migInfo := range m.getMigs() {
|
for _, migInfo := range m.getMigs() {
|
||||||
|
|
@ -505,7 +529,7 @@ func (m *GceManager) regenerateCache() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMigNodes returns mig nodes.
|
// GetMigNodes returns mig nodes.
|
||||||
func (m *GceManager) GetMigNodes(mig *Mig) ([]string, error) {
|
func (m *gceManagerImpl) GetMigNodes(mig *Mig) ([]string, error) {
|
||||||
instances, err := m.gceService.InstanceGroupManagers.ListManagedInstances(mig.Project, mig.Zone, mig.Name).Do()
|
instances, err := m.gceService.InstanceGroupManagers.ListManagedInstances(mig.Project, mig.Zone, mig.Name).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, err
|
return []string{}, err
|
||||||
|
|
@ -521,6 +545,19 @@ func (m *GceManager) GetMigNodes(mig *Mig) ([]string, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *gceManagerImpl) getZone() string {
|
||||||
|
return m.zone
|
||||||
|
}
|
||||||
|
func (m *gceManagerImpl) getProjectId() string {
|
||||||
|
return m.projectId
|
||||||
|
}
|
||||||
|
func (m *gceManagerImpl) getMode() GcpCloudProviderMode {
|
||||||
|
return m.mode
|
||||||
|
}
|
||||||
|
func (m *gceManagerImpl) getTemplates() *templateBuilder {
|
||||||
|
return m.templates
|
||||||
|
}
|
||||||
|
|
||||||
// Code borrowed from gce cloud provider. Reuse the original as soon as it becomes public.
|
// Code borrowed from gce cloud provider. Reuse the original as soon as it becomes public.
|
||||||
func getProjectAndZone() (string, string, error) {
|
func getProjectAndZone() (string, string, error) {
|
||||||
result, err := metadata.Get("instance/zone")
|
result, err := metadata.Get("instance/zone")
|
||||||
|
|
|
||||||
|
|
@ -336,12 +336,12 @@ const managedInstancesResponse2 = `{
|
||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
|
|
||||||
func newTestGceManager(t *testing.T, testServerURL string, mode GcpCloudProviderMode) *GceManager {
|
func newTestGceManager(t *testing.T, testServerURL string, mode GcpCloudProviderMode) *gceManagerImpl {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
gceService, err := gce.New(client)
|
gceService, err := gce.New(client)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
gceService.BasePath = testServerURL
|
gceService.BasePath = testServerURL
|
||||||
manager := &GceManager{
|
manager := &gceManagerImpl{
|
||||||
migs: make([]*migInformation, 0),
|
migs: make([]*migInformation, 0),
|
||||||
gceService: gceService,
|
gceService: gceService,
|
||||||
migCache: make(map[GceRef]*Mig),
|
migCache: make(map[GceRef]*Mig),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue