mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-12-15 16:09:39 -05:00
cloud: fix discovery of GCP nodes across multiple zones (#1943)
This commit is contained in:
parent
de2c21b555
commit
0b262a08bc
4 changed files with 418 additions and 8 deletions
|
|
@ -506,6 +506,26 @@ func TestList(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
otherZoneInstance := &computepb.Instance{
|
||||
Name: proto.String("otherZoneInstance"),
|
||||
Zone: proto.String("someZone-east1-a"),
|
||||
Labels: map[string]string{
|
||||
cloud.TagUID: "1234",
|
||||
cloud.TagRole: role.ControlPlane.String(),
|
||||
},
|
||||
NetworkInterfaces: []*computepb.NetworkInterface{
|
||||
{
|
||||
Name: proto.String("nic0"),
|
||||
NetworkIP: proto.String("192.0.2.1"),
|
||||
AliasIpRanges: []*computepb.AliasIpRange{
|
||||
{
|
||||
IpCidrRange: proto.String("198.51.100.0/24"),
|
||||
},
|
||||
},
|
||||
Subnetwork: proto.String("projects/someProject/regions/someRegion/subnetworks/someSubnetwork"),
|
||||
},
|
||||
},
|
||||
}
|
||||
goodSubnet := &computepb.Subnetwork{
|
||||
SecondaryIpRanges: []*computepb.SubnetworkSecondaryRange{
|
||||
{
|
||||
|
|
@ -516,8 +536,9 @@ func TestList(t *testing.T) {
|
|||
|
||||
testCases := map[string]struct {
|
||||
imds stubIMDS
|
||||
instanceAPI stubInstanceAPI
|
||||
instanceAPI instanceAPI
|
||||
subnetAPI stubSubnetAPI
|
||||
zoneAPI stubZoneAPI
|
||||
wantErr bool
|
||||
wantInstances []metadata.InstanceMetadata
|
||||
}{
|
||||
|
|
@ -527,7 +548,7 @@ func TestList(t *testing.T) {
|
|||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterator: &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
|
|
@ -538,6 +559,15 @@ func TestList(t *testing.T) {
|
|||
subnetAPI: stubSubnetAPI{
|
||||
subnet: goodSubnet,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{
|
||||
Name: proto.String("someZone-west3-b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantInstances: []metadata.InstanceMetadata{
|
||||
{
|
||||
Name: "someInstance",
|
||||
|
|
@ -549,13 +579,64 @@ func TestList(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
"multi-zone": {
|
||||
imds: stubIMDS{
|
||||
projectID: "someProject",
|
||||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: &fakeInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterators: map[string]*stubInstanceIterator{
|
||||
"someZone-east1-a": {
|
||||
instances: []*computepb.Instance{
|
||||
otherZoneInstance,
|
||||
},
|
||||
},
|
||||
"someZone-west3-b": {
|
||||
instances: []*computepb.Instance{
|
||||
goodInstance,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
subnetAPI: stubSubnetAPI{
|
||||
subnet: goodSubnet,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{Name: proto.String("someZone-east1-a")},
|
||||
{Name: proto.String("someZone-west3-b")},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantInstances: []metadata.InstanceMetadata{
|
||||
{
|
||||
Name: "otherZoneInstance",
|
||||
Role: role.ControlPlane,
|
||||
ProviderID: "gce://someProject/someZone-east1-a/otherZoneInstance",
|
||||
VPCIP: "192.0.2.1",
|
||||
AliasIPRanges: []string{"198.51.100.0/24"},
|
||||
SecondaryIPRange: "198.51.100.0/24",
|
||||
},
|
||||
{
|
||||
Name: "someInstance",
|
||||
Role: role.ControlPlane,
|
||||
ProviderID: "gce://someProject/someZone-west3-b/someInstance",
|
||||
VPCIP: "192.0.2.0",
|
||||
AliasIPRanges: []string{"198.51.100.0/24"},
|
||||
SecondaryIPRange: "198.51.100.0/24",
|
||||
},
|
||||
},
|
||||
},
|
||||
"list multiple instances": {
|
||||
imds: stubIMDS{
|
||||
projectID: "someProject",
|
||||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterator: &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
|
|
@ -586,6 +667,15 @@ func TestList(t *testing.T) {
|
|||
subnetAPI: stubSubnetAPI{
|
||||
subnet: goodSubnet,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{
|
||||
Name: proto.String("someZone-west3-b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantInstances: []metadata.InstanceMetadata{
|
||||
{
|
||||
Name: "someInstance",
|
||||
|
|
@ -609,7 +699,7 @@ func TestList(t *testing.T) {
|
|||
imds: stubIMDS{
|
||||
projectIDErr: someErr,
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterator: &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
|
|
@ -628,7 +718,7 @@ func TestList(t *testing.T) {
|
|||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterator: &stubInstanceIterator{
|
||||
err: someErr,
|
||||
|
|
@ -637,6 +727,15 @@ func TestList(t *testing.T) {
|
|||
subnetAPI: stubSubnetAPI{
|
||||
subnet: goodSubnet,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{
|
||||
Name: proto.String("someZone-west3-b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
"get instance error": {
|
||||
|
|
@ -645,7 +744,7 @@ func TestList(t *testing.T) {
|
|||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instanceErr: someErr,
|
||||
iterator: &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
|
|
@ -656,6 +755,15 @@ func TestList(t *testing.T) {
|
|||
subnetAPI: stubSubnetAPI{
|
||||
subnet: goodSubnet,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{
|
||||
Name: proto.String("someZone-west3-b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
"get subnet error": {
|
||||
|
|
@ -664,7 +772,7 @@ func TestList(t *testing.T) {
|
|||
zone: "someZone-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
instanceAPI: stubInstanceAPI{
|
||||
instanceAPI: &stubInstanceAPI{
|
||||
instance: goodInstance,
|
||||
iterator: &stubInstanceIterator{
|
||||
instances: []*computepb.Instance{
|
||||
|
|
@ -675,6 +783,15 @@ func TestList(t *testing.T) {
|
|||
subnetAPI: stubSubnetAPI{
|
||||
subnetErr: someErr,
|
||||
},
|
||||
zoneAPI: stubZoneAPI{
|
||||
iterator: &stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{
|
||||
Name: proto.String("someZone-west3-b"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
|
@ -686,8 +803,9 @@ func TestList(t *testing.T) {
|
|||
|
||||
cloud := &Cloud{
|
||||
imds: &tc.imds,
|
||||
instanceAPI: &tc.instanceAPI,
|
||||
instanceAPI: tc.instanceAPI,
|
||||
subnetAPI: &tc.subnetAPI,
|
||||
zoneAPI: &tc.zoneAPI,
|
||||
}
|
||||
|
||||
instances, err := cloud.List(context.Background())
|
||||
|
|
@ -701,6 +819,112 @@ func TestList(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRegion(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
imds stubIMDS
|
||||
wantRegion string
|
||||
wantErr bool
|
||||
}{
|
||||
"success": {
|
||||
imds: stubIMDS{
|
||||
projectID: "someProject",
|
||||
zone: "someregion-west3-b",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
wantRegion: "someregion-west3",
|
||||
},
|
||||
"get zone error": {
|
||||
imds: stubIMDS{
|
||||
zoneErr: someErr,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
"invalid zone format": {
|
||||
imds: stubIMDS{
|
||||
projectID: "someProject",
|
||||
zone: "invalid",
|
||||
instanceName: "someInstance",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cloud := &Cloud{
|
||||
imds: &tc.imds,
|
||||
}
|
||||
|
||||
assert.Empty(cloud.regionCache)
|
||||
|
||||
gotRegion, err := cloud.region()
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.wantRegion, gotRegion)
|
||||
assert.Equal(tc.wantRegion, cloud.regionCache)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestZones(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
testCases := map[string]struct {
|
||||
zoneAPI stubZoneAPI
|
||||
wantZones []string
|
||||
wantErr bool
|
||||
}{
|
||||
"success": {
|
||||
zoneAPI: stubZoneAPI{
|
||||
&stubZoneIterator{
|
||||
zones: []*computepb.Zone{
|
||||
{Name: proto.String("someregion-west3-b")},
|
||||
{}, // missing name (should be ignored)
|
||||
nil, // nil (should be ignored)
|
||||
},
|
||||
},
|
||||
},
|
||||
wantZones: []string{"someregion-west3-b"},
|
||||
},
|
||||
"get zones error": {
|
||||
zoneAPI: stubZoneAPI{
|
||||
&stubZoneIterator{
|
||||
err: someErr,
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cloud := &Cloud{
|
||||
zoneAPI: &tc.zoneAPI,
|
||||
}
|
||||
|
||||
assert.Empty(cloud.zoneCache)
|
||||
|
||||
gotZones, err := cloud.zones(context.Background(), "someProject", "someregion-west3")
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
assert.Equal(tc.wantZones, gotZones)
|
||||
assert.Equal(tc.wantZones, cloud.zoneCache["someregion-west3"].zones)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveInstanceInfo(t *testing.T) {
|
||||
someErr := errors.New("failed")
|
||||
|
||||
|
|
@ -1035,6 +1259,27 @@ func (s *stubInstanceAPI) List(
|
|||
|
||||
func (s *stubInstanceAPI) Close() error { return nil }
|
||||
|
||||
type fakeInstanceAPI struct {
|
||||
instance *computepb.Instance
|
||||
instanceErr error
|
||||
// iterators is a map of zone to instance iterator.
|
||||
iterators map[string]*stubInstanceIterator
|
||||
}
|
||||
|
||||
func (s *fakeInstanceAPI) Get(
|
||||
_ context.Context, _ *computepb.GetInstanceRequest, _ ...gax.CallOption,
|
||||
) (*computepb.Instance, error) {
|
||||
return s.instance, s.instanceErr
|
||||
}
|
||||
|
||||
func (s *fakeInstanceAPI) List(
|
||||
_ context.Context, req *computepb.ListInstancesRequest, _ ...gax.CallOption,
|
||||
) instanceIterator {
|
||||
return s.iterators[req.GetZone()]
|
||||
}
|
||||
|
||||
func (s *fakeInstanceAPI) Close() error { return nil }
|
||||
|
||||
type stubInstanceIterator struct {
|
||||
ctr int
|
||||
instances []*computepb.Instance
|
||||
|
|
@ -1063,3 +1308,30 @@ func (s *stubSubnetAPI) Get(
|
|||
return s.subnet, s.subnetErr
|
||||
}
|
||||
func (s *stubSubnetAPI) Close() error { return nil }
|
||||
|
||||
type stubZoneAPI struct {
|
||||
iterator *stubZoneIterator
|
||||
}
|
||||
|
||||
func (s *stubZoneAPI) List(_ context.Context,
|
||||
_ *computepb.ListZonesRequest, _ ...gax.CallOption,
|
||||
) zoneIterator {
|
||||
return s.iterator
|
||||
}
|
||||
|
||||
type stubZoneIterator struct {
|
||||
ctr int
|
||||
zones []*computepb.Zone
|
||||
err error
|
||||
}
|
||||
|
||||
func (s *stubZoneIterator) Next() (*computepb.Zone, error) {
|
||||
if s.err != nil {
|
||||
return nil, s.err
|
||||
}
|
||||
if s.ctr >= len(s.zones) {
|
||||
return nil, iterator.Done
|
||||
}
|
||||
s.ctr++
|
||||
return s.zones[s.ctr-1], nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue