Use tags for UID and role parsing (#242)

* Apply tags to all applicable GCP resources

* Move GCP UID and role from VM metadata to labels

* Adjust Azure tags to be in line with GCP and AWS

* Dont rely on resource name to find resources

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-10-24 16:58:21 +02:00 committed by GitHub
parent c2814aeddb
commit b35b74b772
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 344 additions and 360 deletions

View file

@ -12,6 +12,7 @@ import (
"testing"
compute "cloud.google.com/go/compute/apiv1"
"github.com/edgelesssys/constellation/v2/internal/cloud"
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
"github.com/edgelesssys/constellation/v2/internal/role"
gax "github.com/googleapis/gax-go/v2"
@ -38,6 +39,10 @@ func TestRetrieveInstances(t *testing.T) {
instances: []*computepb.Instance{
{
Name: proto.String("someInstance"),
Labels: map[string]string{
cloud.TagRole: role.ControlPlane.String(),
cloud.TagUID: uid,
},
Metadata: &computepb.Metadata{
Items: []*computepb.Items{
{
@ -48,14 +53,6 @@ func TestRetrieveInstances(t *testing.T) {
Key: proto.String("key-2"),
Value: proto.String("value-2"),
},
{
Key: proto.String(constellationUIDMetadataKey),
Value: proto.String(uid),
},
{
Key: proto.String(roleMetadataKey),
Value: proto.String(role.ControlPlane.String()),
},
},
},
NetworkInterfaces: []*computepb.NetworkInterface{
@ -70,6 +67,13 @@ func TestRetrieveInstances(t *testing.T) {
},
}
}
instance := &computepb.Instance{
Name: proto.String("instance"),
Labels: map[string]string{
cloud.TagRole: role.ControlPlane.String(),
cloud.TagUID: uid,
},
}
testCases := map[string]struct {
client stubInstancesClient
@ -80,7 +84,7 @@ func TestRetrieveInstances(t *testing.T) {
wantErr bool
}{
"retrieve works": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
wantInstances: []metadata.InstanceMetadata{
@ -96,14 +100,14 @@ func TestRetrieveInstances(t *testing.T) {
},
},
"instance name is null": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Name = nil },
wantErr: true,
},
"no instance with network ip": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].NetworkInterfaces = nil },
@ -120,7 +124,7 @@ func TestRetrieveInstances(t *testing.T) {
},
},
"network ip is nil": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].NetworkInterfaces[0].NetworkIP = nil },
@ -136,24 +140,17 @@ func TestRetrieveInstances(t *testing.T) {
},
},
},
"constellation id is not set": {
client: stubInstancesClient{},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Metadata.Items[2].Key = proto.String("") },
wantInstances: []metadata.InstanceMetadata{},
},
"constellation retrieval fails": {
client: stubInstancesClient{},
metadata: stubMetadataClient{InstanceErr: someErr},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{instanceIDErr: someErr},
instanceIter: newTestIter(),
wantErr: true,
},
"role is not set": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: newTestIter(),
instanceIterMutator: func(sii *stubInstanceIterator) { sii.instances[0].Metadata.Items[3].Key = proto.String("") },
instanceIterMutator: func(sii *stubInstanceIterator) { delete(sii.instances[0].Labels, cloud.TagRole) },
wantInstances: []metadata.InstanceMetadata{
{
Name: "someInstance",
@ -167,7 +164,7 @@ func TestRetrieveInstances(t *testing.T) {
},
},
"instance iterator Next() errors": {
client: stubInstancesClient{},
client: stubInstancesClient{GetInstance: instance},
metadata: stubMetadataClient{InstanceValue: uid},
instanceIter: &stubInstanceIterator{nextErr: someErr},
wantErr: true,
@ -203,7 +200,8 @@ func TestRetrieveInstances(t *testing.T) {
func TestRetrieveInstance(t *testing.T) {
newTestInstance := func() *computepb.Instance {
return &computepb.Instance{
Name: proto.String("someInstance"),
Name: proto.String("someInstance"),
Labels: map[string]string{},
Metadata: &computepb.Metadata{
Items: []*computepb.Items{
{
@ -266,8 +264,7 @@ func TestRetrieveInstance(t *testing.T) {
client: stubInstancesClient{},
clientInstance: newTestInstance(),
clientInstanceMutator: func(i *computepb.Instance) {
i.Metadata.Items[0].Key = proto.String(roleMetadataKey)
i.Metadata.Items[0].Value = proto.String(role.ControlPlane.String())
i.Labels[cloud.TagRole] = role.ControlPlane.String()
},
wantInstance: metadata.InstanceMetadata{
Name: "someInstance",
@ -782,22 +779,31 @@ func TestRetrieveSubnetworkAliasCIDR(t *testing.T) {
func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
loadBalancerIP := "192.0.2.1"
uid := "uid"
use := "kubernetes"
someErr := errors.New("some error")
instance := &computepb.Instance{
Labels: map[string]string{
cloud.TagUID: uid,
},
}
testCases := map[string]struct {
instanceAPI stubInstancesClient
stubForwardingRulesClient stubForwardingRulesClient
stubMetadataClient stubMetadataClient
wantLoadBalancerIP string
wantErr bool
}{
"works": {
stubMetadataClient: stubMetadataClient{InstanceValue: uid},
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
rules: []*computepb.ForwardingRule{
{
IPAddress: proto.String(loadBalancerIP),
PortRange: proto.String("100-100"),
Labels: map[string]string{"constellation-uid": uid},
Labels: map[string]string{cloud.TagUID: uid, "constellation-use": use},
},
},
},
@ -805,7 +811,8 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
wantLoadBalancerIP: loadBalancerIP,
},
"fails when no matching load balancers exists": {
stubMetadataClient: stubMetadataClient{InstanceValue: uid},
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
rules: []*computepb.ForwardingRule{
@ -819,14 +826,15 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
wantErr: true,
},
"fails when retrieving uid": {
stubMetadataClient: stubMetadataClient{InstanceErr: someErr},
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{instanceIDErr: someErr},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
rules: []*computepb.ForwardingRule{
{
IPAddress: proto.String(loadBalancerIP),
PortRange: proto.String("100-100"),
Labels: map[string]string{"constellation-uid": uid},
Labels: map[string]string{cloud.TagUID: uid, "constellation-use": use},
},
},
},
@ -834,13 +842,14 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
wantErr: true,
},
"fails when answer has empty port range": {
stubMetadataClient: stubMetadataClient{InstanceErr: someErr},
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
rules: []*computepb.ForwardingRule{
{
IPAddress: proto.String(loadBalancerIP),
Labels: map[string]string{"constellation-uid": uid},
Labels: map[string]string{cloud.TagUID: uid, "constellation-use": use},
},
},
},
@ -848,6 +857,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
wantErr: true,
},
"fails when retrieving loadbalancer IP": {
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
@ -856,7 +866,23 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
{
IPAddress: proto.String(loadBalancerIP),
PortRange: proto.String("100-100"),
Labels: map[string]string{"constellation-uid": uid},
Labels: map[string]string{cloud.TagUID: uid, "constellation-use": use},
},
},
},
},
wantErr: true,
},
"fails on incorrect use label": {
instanceAPI: stubInstancesClient{GetInstance: instance},
stubMetadataClient: stubMetadataClient{InstanceValue: uid},
stubForwardingRulesClient: stubForwardingRulesClient{
ForwardingRuleIterator: &stubForwardingRuleIterator{
rules: []*computepb.ForwardingRule{
{
IPAddress: proto.String(loadBalancerIP),
PortRange: proto.String("100-100"),
Labels: map[string]string{cloud.TagUID: uid, "constellation-use": "bootstrapper"},
},
},
},
@ -869,7 +895,7 @@ func TestRetrieveLoadBalancerEndpoint(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
client := Client{forwardingRulesAPI: tc.stubForwardingRulesClient, metadataAPI: tc.stubMetadataClient}
client := Client{instanceAPI: tc.instanceAPI, forwardingRulesAPI: tc.stubForwardingRulesClient, metadataAPI: tc.stubMetadataClient}
aliasCIDR, err := client.RetrieveLoadBalancerEndpoint(context.Background(), "project")
if tc.wantErr {
@ -1049,6 +1075,8 @@ func (s stubForwardingRulesClient) Close() error {
type stubMetadataClient struct {
InstanceValue string
InstanceErr error
instanceIDValue string
instanceIDErr error
ProjectIDValue string
ProjectIDErr error
ZoneValue string
@ -1061,6 +1089,10 @@ func (s stubMetadataClient) InstanceAttributeValue(attr string) (string, error)
return s.InstanceValue, s.InstanceErr
}
func (s stubMetadataClient) InstanceID() (string, error) {
return s.instanceIDValue, s.instanceIDErr
}
func (s stubMetadataClient) ProjectID() (string, error) {
return s.ProjectIDValue, s.ProjectIDErr
}