From aba75d216c60b294893e34b601a83e199dfabd78 Mon Sep 17 00:00:00 2001
From: Christian Banse <oxisto@clouditor.io>
Date: Sun, 28 Aug 2022 13:48:52 +0200
Subject: [PATCH 1/3] Added AWS support in workload collection module

---
 api/collection/collection.pb.go               |  89 +++++-----
 api/collection/collection.proto               |   1 +
 api/collection/errors.go                      |   1 +
 api/common/evidence.pb.go                     |   2 +-
 api/configuration/configuration.pb.go         |   2 +-
 api/configuration/configuration.pb.gw.go      | 152 +++++++++++-------
 api/evaluation/evaluation.pb.go               |   2 +-
 api/evaluation/evaluation.pb.gw.go            |  52 +++---
 dashboard/src/data/model.ts                   |   7 +
 dashboard/src/views/ConfigurationDetail.vue   |  26 ++-
 go.mod                                        |  23 ++-
 go.sum                                        |  50 ++++++
 .../collection/workload/aws/strct/strct.go    |  39 +++++
 service/collection/workload/server.go         |  51 ++++++
 14 files changed, 368 insertions(+), 129 deletions(-)
 create mode 100644 service/collection/workload/aws/strct/strct.go

diff --git a/api/collection/collection.pb.go b/api/collection/collection.pb.go
index c4092078..126cd175 100644
--- a/api/collection/collection.pb.go
+++ b/api/collection/collection.pb.go
@@ -15,7 +15,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.28.0
+// 	protoc-gen-go v1.28.1
 // 	protoc        v3.21.5
 // source: api/collection/collection.proto
 
@@ -428,13 +428,10 @@ type AuthenticationSecurityConfig struct {
 	// Optional. The URL for Authorization Server Metadata (RFC8414)
 	MetadataDocument string `protobuf:"bytes,2,opt,name=metadata_document,json=metadataDocument,proto3" json:"metadata_document,omitempty"`
 	// Required? ...
-	ApiEndpoint string `protobuf:"bytes,3,opt,name=api_endpoint,json=apiEndpoint,proto3" json:"api_endpoint,omitempty"`
-	//
-	ClientId string `protobuf:"bytes,4,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
-	//
+	ApiEndpoint  string `protobuf:"bytes,3,opt,name=api_endpoint,json=apiEndpoint,proto3" json:"api_endpoint,omitempty"`
+	ClientId     string `protobuf:"bytes,4,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
 	ClientSecret string `protobuf:"bytes,5,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
-	//
-	Scopes string `protobuf:"bytes,6,opt,name=scopes,proto3" json:"scopes,omitempty"`
+	Scopes       string `protobuf:"bytes,6,opt,name=scopes,proto3" json:"scopes,omitempty"`
 }
 
 func (x *AuthenticationSecurityConfig) Reset() {
@@ -575,6 +572,7 @@ type WorkloadSecurityConfig struct {
 	// TODO(lebogg to garuppel): We could use oneof
 	Openstack  *structpb.Value `protobuf:"bytes,1,opt,name=openstack,proto3" json:"openstack,omitempty"`
 	Kubernetes *structpb.Value `protobuf:"bytes,2,opt,name=kubernetes,proto3" json:"kubernetes,omitempty"`
+	Aws        *structpb.Value `protobuf:"bytes,3,opt,name=aws,proto3" json:"aws,omitempty"`
 }
 
 func (x *WorkloadSecurityConfig) Reset() {
@@ -623,6 +621,13 @@ func (x *WorkloadSecurityConfig) GetKubernetes() *structpb.Value {
 	return nil
 }
 
+func (x *WorkloadSecurityConfig) GetAws() *structpb.Value {
+	if x != nil {
+		return x.Aws
+	}
+	return nil
+}
+
 var File_api_collection_collection_proto protoreflect.FileDescriptor
 
 var file_api_collection_collection_proto_rawDesc = []byte{
@@ -707,7 +712,7 @@ var file_api_collection_collection_proto_rawDesc = []byte{
 	0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65,
 	0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x86, 0x01, 0x0a,
+	0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0xb0, 0x01, 0x0a,
 	0x16, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
 	0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x73,
 	0x74, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
@@ -716,27 +721,30 @@ var file_api_collection_collection_proto_rawDesc = []byte{
 	0x0a, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 	0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x65, 0x73, 0x32, 0xf0, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c,
-	0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74,
-	0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74,
-	0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
-	0x74, 0x69, 0x6e, 0x67, 0x12, 0x1a, 0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43,
-	0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72,
-	0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61,
-	0x6d, 0x12, 0x1b, 0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c,
-	0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
-	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x6c,
-	0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x69, 0x61, 0x2d, 0x78, 0x2f, 0x64, 0x61,
-	0x74, 0x61, 0x2d, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72,
-	0x65, 0x2d, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6e, 0x65, 0x74, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x03, 0x61, 0x77, 0x73, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x61, 0x77, 0x73, 0x32,
+	0xf0, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4c,
+	0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e,
+	0x67, 0x12, 0x1b, 0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c,
+	0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c,
+	0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
+	0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e,
+	0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1a,
+	0x2e, 0x63, 0x61, 0x6d, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+	0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
+	0x74, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
+	0x63, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1b, 0x2e, 0x63, 0x61,
+	0x6d, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6e,
+	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
+	0x28, 0x01, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2f, 0x67, 0x61, 0x69, 0x61, 0x2d, 0x78, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x69, 0x6e, 0x66,
+	0x72, 0x61, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x66, 0x65, 0x64, 0x65,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
+	0x63, 0x61, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+	0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -773,17 +781,18 @@ var file_api_collection_collection_proto_depIdxs = []int32{
 	10, // 2: cam.CollectionModule.metrics:type_name -> clouditor.Metric
 	11, // 3: cam.WorkloadSecurityConfig.openstack:type_name -> google.protobuf.Value
 	11, // 4: cam.WorkloadSecurityConfig.kubernetes:type_name -> google.protobuf.Value
-	1,  // 5: cam.Collection.StartCollecting:input_type -> cam.StartCollectingRequest
-	3,  // 6: cam.Collection.StopCollecting:input_type -> cam.StopCollectingRequest
-	1,  // 7: cam.Collection.StartCollectingStream:input_type -> cam.StartCollectingRequest
-	2,  // 8: cam.Collection.StartCollecting:output_type -> cam.StartCollectingResponse
-	12, // 9: cam.Collection.StopCollecting:output_type -> google.protobuf.Empty
-	12, // 10: cam.Collection.StartCollectingStream:output_type -> google.protobuf.Empty
-	8,  // [8:11] is the sub-list for method output_type
-	5,  // [5:8] is the sub-list for method input_type
-	5,  // [5:5] is the sub-list for extension type_name
-	5,  // [5:5] is the sub-list for extension extendee
-	0,  // [0:5] is the sub-list for field type_name
+	11, // 5: cam.WorkloadSecurityConfig.aws:type_name -> google.protobuf.Value
+	1,  // 6: cam.Collection.StartCollecting:input_type -> cam.StartCollectingRequest
+	3,  // 7: cam.Collection.StopCollecting:input_type -> cam.StopCollectingRequest
+	1,  // 8: cam.Collection.StartCollectingStream:input_type -> cam.StartCollectingRequest
+	2,  // 9: cam.Collection.StartCollecting:output_type -> cam.StartCollectingResponse
+	12, // 10: cam.Collection.StopCollecting:output_type -> google.protobuf.Empty
+	12, // 11: cam.Collection.StartCollectingStream:output_type -> google.protobuf.Empty
+	9,  // [9:12] is the sub-list for method output_type
+	6,  // [6:9] is the sub-list for method input_type
+	6,  // [6:6] is the sub-list for extension type_name
+	6,  // [6:6] is the sub-list for extension extendee
+	0,  // [0:6] is the sub-list for field type_name
 }
 
 func init() { file_api_collection_collection_proto_init() }
diff --git a/api/collection/collection.proto b/api/collection/collection.proto
index e9415c7a..f5d055f7 100644
--- a/api/collection/collection.proto
+++ b/api/collection/collection.proto
@@ -122,4 +122,5 @@ message WorkloadSecurityConfig {
   // TODO(lebogg to garuppel): We could use oneof
   google.protobuf.Value openstack = 1;
   google.protobuf.Value kubernetes = 2;
+  google.protobuf.Value aws = 3;
 }
\ No newline at end of file
diff --git a/api/collection/errors.go b/api/collection/errors.go
index 929cb54e..3ea78405 100644
--- a/api/collection/errors.go
+++ b/api/collection/errors.go
@@ -31,6 +31,7 @@ var (
 	ErrInvalidWorkloadConfigurationRawConfiguration = errors.New("no workload raw configuration")
 	ErrInvalidKubernetesServiceConfiguration        = errors.New("kubernetes service configuration is invalid")
 	ErrInvalidOpenstackServiceConfiguration         = errors.New("could not store openstack service configuration")
+	ErrInvalidAWSServiceConfiguration               = errors.New("could not store aws service configuration")
 	ErrConversionProtobufToByteArray                = errors.New("could not convert protobuf value to byte array")
 	ErrKubernetesClientset                          = errors.New("could not get kubernetes clientset")
 	ErrConversionProtobufToAuthOptions              = errors.New("could not convert protobuf value to openstack.authOptions")
diff --git a/api/common/evidence.pb.go b/api/common/evidence.pb.go
index d6bbb7ee..3e46a1b1 100644
--- a/api/common/evidence.pb.go
+++ b/api/common/evidence.pb.go
@@ -15,7 +15,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.28.0
+// 	protoc-gen-go v1.28.1
 // 	protoc        v3.21.5
 // source: api/common/evidence.proto
 
diff --git a/api/configuration/configuration.pb.go b/api/configuration/configuration.pb.go
index f0ce5fcd..f11670e3 100644
--- a/api/configuration/configuration.pb.go
+++ b/api/configuration/configuration.pb.go
@@ -15,7 +15,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.28.0
+// 	protoc-gen-go v1.28.1
 // 	protoc        v3.21.5
 // source: api/configuration/configuration.proto
 
diff --git a/api/configuration/configuration.pb.gw.go b/api/configuration/configuration.pb.gw.go
index 4a457788..bb1ad6cc 100644
--- a/api/configuration/configuration.pb.gw.go
+++ b/api/configuration/configuration.pb.gw.go
@@ -862,12 +862,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/StartMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/start"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/StartMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/start"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_StartMonitoring_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_StartMonitoring_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -885,12 +886,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/StopMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/stop"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/StopMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/stop"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_StopMonitoring_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_StopMonitoring_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -908,12 +910,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMonitoringStatus", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMonitoringStatus", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_GetMonitoringStatus_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_GetMonitoringStatus_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -931,12 +934,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListMetrics", runtime.WithHTTPPathPattern("/v1/configuration/metrics"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListMetrics", runtime.WithHTTPPathPattern("/v1/configuration/metrics"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_ListMetrics_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_ListMetrics_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -954,12 +958,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMetric", runtime.WithHTTPPathPattern("/v1/configuration/metrics/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMetric", runtime.WithHTTPPathPattern("/v1/configuration/metrics/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_GetMetric_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_GetMetric_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -977,12 +982,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_GetMetricConfiguration_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_GetMetricConfiguration_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1000,12 +1006,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/UpdateMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/UpdateMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_UpdateMetricConfiguration_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_UpdateMetricConfiguration_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1023,12 +1030,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_RegisterCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_RegisterCloudService_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1046,12 +1054,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_UpdateCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_UpdateCloudService_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1069,12 +1078,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ConfigureCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ConfigureCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_ConfigureCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_ConfigureCloudService_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1092,12 +1102,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListCloudServiceConfigurations", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListCloudServiceConfigurations", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_ListCloudServiceConfigurations_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_ListCloudServiceConfigurations_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1115,12 +1126,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/GetCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_GetCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_GetCloudService_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1138,12 +1150,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListCloudServices", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListCloudServices", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_ListCloudServices_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_ListCloudServices_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1161,12 +1174,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_RemoveCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_RemoveCloudService_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1184,12 +1198,13 @@ func RegisterConfigurationHandlerServer(ctx context.Context, mux *runtime.ServeM
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListControls", runtime.WithHTTPPathPattern("/v1/configuration/controls"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Configuration/ListControls", runtime.WithHTTPPathPattern("/v1/configuration/controls"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Configuration_ListControls_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Configuration_ListControls_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -1231,7 +1246,7 @@ func RegisterConfigurationHandlerFromEndpoint(ctx context.Context, mux *runtime.
 
 // RegisterConfigurationHandler registers the http handlers for service Configuration to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterConfigurationHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
+func RegisterConfigurationHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
 	return RegisterConfigurationHandlerClient(ctx, mux, NewConfigurationClient(conn))
 }
 
@@ -1246,12 +1261,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/StartMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/start"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/StartMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/start"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_StartMonitoring_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_StartMonitoring_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1266,12 +1282,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/StopMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/stop"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/StopMonitoring", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}/stop"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_StopMonitoring_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_StopMonitoring_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1286,12 +1303,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMonitoringStatus", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMonitoringStatus", runtime.WithHTTPPathPattern("/v1/configuration/monitoring/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_GetMonitoringStatus_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_GetMonitoringStatus_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1306,12 +1324,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListMetrics", runtime.WithHTTPPathPattern("/v1/configuration/metrics"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListMetrics", runtime.WithHTTPPathPattern("/v1/configuration/metrics"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_ListMetrics_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_ListMetrics_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1326,12 +1345,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMetric", runtime.WithHTTPPathPattern("/v1/configuration/metrics/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMetric", runtime.WithHTTPPathPattern("/v1/configuration/metrics/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_GetMetric_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_GetMetric_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1346,12 +1366,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_GetMetricConfiguration_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_GetMetricConfiguration_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1366,12 +1387,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/UpdateMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/UpdateMetricConfiguration", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/metric_configurations/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_UpdateMetricConfiguration_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_UpdateMetricConfiguration_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1386,12 +1408,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_RegisterCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_RegisterCloudService_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1406,12 +1429,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_UpdateCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_UpdateCloudService_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1426,12 +1450,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ConfigureCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ConfigureCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_ConfigureCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_ConfigureCloudService_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1446,12 +1471,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListCloudServiceConfigurations", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListCloudServiceConfigurations", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}/configurations"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_ListCloudServiceConfigurations_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_ListCloudServiceConfigurations_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1466,12 +1492,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/GetCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_GetCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_GetCloudService_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1486,12 +1513,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListCloudServices", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListCloudServices", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_ListCloudServices_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_ListCloudServices_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1506,12 +1534,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/configuration/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_RemoveCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_RemoveCloudService_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -1526,12 +1555,13 @@ func RegisterConfigurationHandlerClient(ctx context.Context, mux *runtime.ServeM
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListControls", runtime.WithHTTPPathPattern("/v1/configuration/controls"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Configuration/ListControls", runtime.WithHTTPPathPattern("/v1/configuration/controls"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Configuration_ListControls_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Configuration_ListControls_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
diff --git a/api/evaluation/evaluation.pb.go b/api/evaluation/evaluation.pb.go
index a300654c..2289dada 100644
--- a/api/evaluation/evaluation.pb.go
+++ b/api/evaluation/evaluation.pb.go
@@ -15,7 +15,7 @@
 
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.28.0
+// 	protoc-gen-go v1.28.1
 // 	protoc        v3.21.5
 // source: api/evaluation/evaluation.proto
 
diff --git a/api/evaluation/evaluation.pb.gw.go b/api/evaluation/evaluation.pb.gw.go
index 9e597728..5a7f7daa 100644
--- a/api/evaluation/evaluation.pb.gw.go
+++ b/api/evaluation/evaluation.pb.gw.go
@@ -379,12 +379,13 @@ func RegisterEvaluationHandlerServer(ctx context.Context, mux *runtime.ServeMux,
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetEvidence", runtime.WithHTTPPathPattern("/v1/evaluation/evidences/{evidence_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetEvidence", runtime.WithHTTPPathPattern("/v1/evaluation/evidences/{evidence_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Evaluation_GetEvidence_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Evaluation_GetEvidence_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -402,12 +403,13 @@ func RegisterEvaluationHandlerServer(ctx context.Context, mux *runtime.ServeMux,
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/ListEvidences", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/evidences"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/ListEvidences", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/evidences"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Evaluation_ListEvidences_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Evaluation_ListEvidences_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -425,12 +427,13 @@ func RegisterEvaluationHandlerServer(ctx context.Context, mux *runtime.ServeMux,
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetEvaluation", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/metrics/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetEvaluation", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/metrics/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Evaluation_GetEvaluation_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Evaluation_GetEvaluation_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -448,12 +451,13 @@ func RegisterEvaluationHandlerServer(ctx context.Context, mux *runtime.ServeMux,
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/controls/{control_id}"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/GetCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/controls/{control_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Evaluation_GetCompliance_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Evaluation_GetCompliance_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -471,12 +475,13 @@ func RegisterEvaluationHandlerServer(ctx context.Context, mux *runtime.ServeMux,
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/ListCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/compliance"))
+		var err error
+		ctx, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/cam.Evaluation/ListCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/compliance"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Evaluation_ListCompliance_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Evaluation_ListCompliance_0(ctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -518,7 +523,7 @@ func RegisterEvaluationHandlerFromEndpoint(ctx context.Context, mux *runtime.Ser
 
 // RegisterEvaluationHandler registers the http handlers for service Evaluation to "mux".
 // The handlers forward requests to the grpc endpoint over "conn".
-func RegisterEvaluationHandler(ctx context.Context, mux *runtime.ServeMux, conn grpc.ClientConnInterface) error {
+func RegisterEvaluationHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
 	return RegisterEvaluationHandlerClient(ctx, mux, NewEvaluationClient(conn))
 }
 
@@ -533,12 +538,13 @@ func RegisterEvaluationHandlerClient(ctx context.Context, mux *runtime.ServeMux,
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetEvidence", runtime.WithHTTPPathPattern("/v1/evaluation/evidences/{evidence_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetEvidence", runtime.WithHTTPPathPattern("/v1/evaluation/evidences/{evidence_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Evaluation_GetEvidence_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Evaluation_GetEvidence_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -553,12 +559,13 @@ func RegisterEvaluationHandlerClient(ctx context.Context, mux *runtime.ServeMux,
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/ListEvidences", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/evidences"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/ListEvidences", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/evidences"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Evaluation_ListEvidences_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Evaluation_ListEvidences_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -573,12 +580,13 @@ func RegisterEvaluationHandlerClient(ctx context.Context, mux *runtime.ServeMux,
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetEvaluation", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/metrics/{metric_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetEvaluation", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/metrics/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Evaluation_GetEvaluation_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Evaluation_GetEvaluation_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -593,12 +601,13 @@ func RegisterEvaluationHandlerClient(ctx context.Context, mux *runtime.ServeMux,
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/controls/{control_id}"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/GetCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/controls/{control_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Evaluation_GetCompliance_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Evaluation_GetCompliance_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
@@ -613,12 +622,13 @@ func RegisterEvaluationHandlerClient(ctx context.Context, mux *runtime.ServeMux,
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/ListCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/compliance"))
+		var err error
+		ctx, err = runtime.AnnotateContext(ctx, mux, req, "/cam.Evaluation/ListCompliance", runtime.WithHTTPPathPattern("/v1/evaluation/cloud_services/{service_id}/compliance"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := request_Evaluation_ListCompliance_0(rctx, inboundMarshaler, client, req, pathParams)
+		resp, md, err := request_Evaluation_ListCompliance_0(ctx, inboundMarshaler, client, req, pathParams)
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
diff --git a/dashboard/src/data/model.ts b/dashboard/src/data/model.ts
index dc8b7d41..7af48c33 100644
--- a/dashboard/src/data/model.ts
+++ b/dashboard/src/data/model.ts
@@ -76,6 +76,7 @@ export interface WorkloadSecurityConfig extends BaseConfig {
   //"@type": "type.googleapis.com/cam.WorkloadSecurityConfig"
   kubernetes: String | ArrayBuffer | null | undefined,
   openstack: OpenStackConfiguration,
+  aws: AWSConfiguration,
 }
 
 export interface OpenStackConfiguration extends BaseConfig {
@@ -86,6 +87,12 @@ export interface OpenStackConfiguration extends BaseConfig {
   password: string,
 }
 
+export interface AWSConfiguration extends BaseConfig {
+  region: string,
+  accessKeyId: string
+  secretAccessKey: string
+}
+
 export interface ServiceConfiguration {
   serviceId: string
   rawConfiguration: CommunicationSecurityConfig |
diff --git a/dashboard/src/views/ConfigurationDetail.vue b/dashboard/src/views/ConfigurationDetail.vue
index 3cfb6319..655b9ac8 100644
--- a/dashboard/src/views/ConfigurationDetail.vue
+++ b/dashboard/src/views/ConfigurationDetail.vue
@@ -99,7 +99,7 @@ function configFor<T extends
     }
 
     if (module == "type.googleapis.com/cam.WorkloadSecurityConfig") {
-        return { openstack: {}, kubernetes: {}, "@type": module } as T;
+        return { openstack: {}, kubernetes: {}, aws: {}, "@type": module } as T;
     } else {
         return { "@type": module } as T;
     }
@@ -124,6 +124,9 @@ function id(local: string): string {
                 <input type="radio" id="openstack" value="openstack" v-model="kubernetes" class="me-1" />
                 <label for="openstack" class="me-2">OpenStack</label>
 
+                <input type="radio" id="aws" value="aws" v-model="kubernetes" class="me-1" />
+                <label for="aws" class="me-2">AWS</label>
+
                 <!-- kubernetes: -->
                 <div v-if="kubernetes == 'kubernetes'">
                     <h6 class="card-title mt-2">Kubernetes config</h6>
@@ -135,7 +138,7 @@ function id(local: string): string {
                     </button>
                 </div>
                 <!-- openstack: -->
-                <div v-else>
+                <div v-else-if="kubernetes == 'openstack'">
                     <h6 class="card-title mt-2">OpenStack config</h6>
 
                     <div class="form-group">
@@ -164,6 +167,25 @@ function id(local: string): string {
                             type="password" class="form-control" />
                     </div>
                 </div>
+                <!-- AWS: -->
+                <div v-else>
+                    <h6 class="card-title mt-2">AWS config</h6>
+
+                    <div class="form-group">
+                        <label :for="id('aws-region')">Region</label>
+                        <input :id="id('aws-region')" v-model="workloadConfig.aws.region" class="form-control" />
+                    </div>
+                    <div class="form-group">
+                        <label :for="id('aws-access-key-id')">Access Key ID</label>
+                        <input :id="id('aws-access-key-id')" v-model="workloadConfig.aws.accessKeyId"
+                            class="form-control" />
+                    </div>
+                    <div class="form-group">
+                        <label :for="id('aws-secret-access-key')">Secret Access Key</label>
+                        <input :id="id('aws-secret-access-key')" v-model="workloadConfig.aws.secretAccessKey"
+                            type="password" class="form-control" />
+                    </div>
+                </div>
             </div>
         </div>
 
diff --git a/go.mod b/go.mod
index 05692d17..94cf9645 100644
--- a/go.mod
+++ b/go.mod
@@ -14,6 +14,7 @@ require (
 	github.com/sirupsen/logrus v1.9.0
 	github.com/spf13/cobra v1.5.0
 	github.com/spf13/viper v1.12.0
+	golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
 	golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c
 	google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b
 	google.golang.org/grpc v1.48.0
@@ -33,14 +34,31 @@ require (
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0
 )
 
-require golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
-
 require (
 	github.com/MicahParks/keyfunc v1.2.0 // indirect
 	github.com/OneOfOne/xxhash v1.2.8 // indirect
 	github.com/PuerkitoBio/purell v1.1.1 // indirect
 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
 	github.com/agnivade/levenshtein v1.0.1 // indirect
+	github.com/aws/aws-sdk-go-v2 v1.16.11 // indirect
+	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect
+	github.com/aws/aws-sdk-go-v2/config v1.17.0 // indirect
+	github.com/aws/aws-sdk-go-v2/credentials v1.12.13 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.5 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ec2 v1.52.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.9 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.8 // indirect
+	github.com/aws/aws-sdk-go-v2/service/lambda v1.23.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/s3 v1.27.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.11.16 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 // indirect
+	github.com/aws/smithy-go v1.12.1 // indirect
 	github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/emicklei/go-restful v2.9.5+incompatible // indirect
@@ -71,6 +89,7 @@ require (
 	github.com/jackc/pgx/v4 v4.15.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/logrusorgru/aurora/v3 v3.0.0 // indirect
diff --git a/go.sum b/go.sum
index 49eb0fd7..214c6e6a 100644
--- a/go.sum
+++ b/go.sum
@@ -131,6 +131,53 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
 github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
 github.com/aws/aws-sdk-go v1.43.16/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go-v2 v1.16.3/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
+github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw=
+github.com/aws/aws-sdk-go-v2 v1.16.11 h1:xM1ZPSvty3xVmdxiGr7ay/wlqv+MWhH0rMlyLdbC0YQ=
+github.com/aws/aws-sdk-go-v2 v1.16.11/go.mod h1:WTACcleLz6VZTp7fak4EO5b9Q4foxbn+8PIz3PmyKlo=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y=
+github.com/aws/aws-sdk-go-v2/config v1.17.0 h1:e0tIuubcjp0gJQdllgEMwolWWXGK/sKAFd1tS5S6m6I=
+github.com/aws/aws-sdk-go-v2/config v1.17.0/go.mod h1:4SKzBMiB8lV0fw2w7eDBo/LjQyHFITN4vUUuqpurFmI=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.13 h1:cuPzIsjKAWBUAAk8ZUR2l02Sxafl9hiaMsc7tlnjwAY=
+github.com/aws/aws-sdk-go-v2/credentials v1.12.13/go.mod h1:9fDEemXizwXrxPU1MTzv69LP/9D8HVl5qHAQO9A9ikY=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12 h1:wgJBHO58Pc1V1QAnzdVM3JK3WbE/6eUF0JxCZ+/izz0=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.12/go.mod h1:aZ4vZnyUuxedC7eD4JyEHpGnCz+O2sHQEx3VvAwklSE=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14/go.mod h1:kdjrMwHwrC3+FsKhNcCMJ7tUVj/8uSD5CZXeQ4wV6fM=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18 h1:OmiwoVyLKEqqD5GvB683dbSqxiOfvx4U2lDZhG2Esc4=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.18/go.mod h1:348MLhzV1GSlZSMusdwQpXKbhD7X2gbI/TxwAPKkYZQ=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8/go.mod h1:ZIV8GYoC6WLBW5KGs+o4rsc65/ozd+eQ0L31XF5VDwk=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12 h1:5mvQDtNWtI6H56+E4LUnLWEmATMB7oEh+Z9RurtIuC0=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.12/go.mod h1:ckaCVTEdGAxO6KwTGzgskxR1xM+iJW4lxMyDFVda2Fc=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19 h1:g5qq9sgtEzt2szMaDqQO6fqKe026T6dHTFJp5NsPzkQ=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.3.19/go.mod h1:cVHo8KTuHjShb9V8/VjH3S/8+xPu16qx8fdGwmotJhE=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.5 h1:tEEHn+PGAxRVqMPEhtU8oCSW/1Ge3zP5nUgPrGQNUPs=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.5/go.mod h1:aIwFF3dUk95ocCcA3zfk3nhz0oLkpzHFWuMp8l/4nNs=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.52.1 h1:A2hit+4GRYOdvs2aJxGhDrrRS17zSa66M+k1IqqgUic=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.52.1/go.mod h1:YbPg6ou7dlvFTJMmbV3zhec+A22S1Ow+ZB6k6xUs9oY=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 h1:4n4KCtv5SUoT5Er5XV41huuzrCqepxlW3SDI9qHQebc=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.9 h1:gVv2vXOMqJeR4ZHHV32K7LElIJIIzyw/RU1b0lSfWTQ=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.9/go.mod h1:EF5RLnD9l0xvEWwMRcktIS/dI6lF8lU5eV3B13k6sWo=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8/go.mod h1:rDVhIMAX9N2r8nWxDUlbubvvaFMnfsm+3jAV7q+rpM4=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12 h1:7iPTTX4SAI2U2VOogD7/gmHlsgnYSgoNHt7MSQXtG2M=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.12/go.mod h1:1TODGhheLWjpQWSuhYuAUWYTCKwEjx2iblIFKDHjeTc=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.8 h1:TlN1UC39A0LUNoD51ubO5h32haznA+oVe15jO9O4Lj0=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.8/go.mod h1:JlVwmWtT/1c5W+6oUsjXjAJ0iJZ+hlghdrDy/8JxGCU=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.23.0 h1:kmQZYVGPMKh8JYoKMAqkuOi/EDy+lTCehbDCTaRwN2E=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.23.0/go.mod h1:ycMbsJsb4AE4347l42J9YvY9ct6DcMv5Pk1hlfxtsJU=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.27.1 h1:OKQIQ0QhEBmGr2LfT952meIZz3ujrPYnxH+dO/5ldnI=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.27.1/go.mod h1:NffjpNsMUFXp6Ok/PahrktAncoekWrywvmIK83Q2raE=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.16 h1:YK8L7TNlGwMWHYqLs+i6dlITpxqzq08FqQUy26nm+T8=
+github.com/aws/aws-sdk-go-v2/service/sso v1.11.16/go.mod h1:mS5xqLZc/6kc06IpXn5vRxdLaED+jEuaSRv5BxtnsiY=
+github.com/aws/aws-sdk-go-v2/service/sts v1.16.13 h1:dl8T0PJlN92rvEGOEUiD0+YPYdPEaCZK0TqHukvSfII=
+github.com/aws/aws-sdk-go-v2/service/sts v1.16.13/go.mod h1:Ru3QVMLygVs/07UQ3YDur1AQZZp2tUNje8wfloFttC0=
+github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
+github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
+github.com/aws/smithy-go v1.12.1 h1:yQRC55aXN/y1W10HgwHle01DRuV9Dpf31iGkotjt3Ag=
+github.com/aws/smithy-go v1.12.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
 github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
 github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -540,6 +587,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
 github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI=
 github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw=
@@ -696,7 +744,9 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
diff --git a/service/collection/workload/aws/strct/strct.go b/service/collection/workload/aws/strct/strct.go
new file mode 100644
index 00000000..fc4df3a8
--- /dev/null
+++ b/service/collection/workload/aws/strct/strct.go
@@ -0,0 +1,39 @@
+package strct
+
+import (
+	"encoding/json"
+	"fmt"
+
+	"google.golang.org/protobuf/types/known/structpb"
+)
+
+type AWSConfig struct {
+	Region          string `json:"region"`
+	AccessKeyID     string `json:"accessKeyId"`
+	SecretAccessKey string `json:"secretAccessKey"`
+}
+
+// ToConfig converts the protobuf value to an AWS Config
+func ToConfig(v *structpb.Value) (config *AWSConfig, err error) {
+	value := v.GetStructValue().AsMap()
+
+	if len(value) == 0 {
+		err = fmt.Errorf("converting raw configuration to map is empty or nil")
+		return
+	}
+
+	// First, we have to marshal the configuration map
+	body, err := json.Marshal(value)
+	if err != nil {
+		err = fmt.Errorf("could not marshal configuration")
+		return
+	}
+
+	// Then, we can store it back to the gophercloud.AuthOptions
+	if err = json.Unmarshal(body, &config); err != nil {
+		err = fmt.Errorf("could not parse configuration: %w", err)
+		return
+	}
+
+	return
+}
diff --git a/service/collection/workload/server.go b/service/collection/workload/server.go
index 08e3cc0f..aab93e6b 100644
--- a/service/collection/workload/server.go
+++ b/service/collection/workload/server.go
@@ -19,10 +19,12 @@ package workload
 import (
 	"context"
 	"fmt"
+	"os"
 	"sync"
 
 	clapi "clouditor.io/clouditor/api"
 	clapidiscovery "clouditor.io/clouditor/api/discovery"
+	"clouditor.io/clouditor/service/discovery/aws"
 	"clouditor.io/clouditor/service/discovery/k8s"
 	"clouditor.io/clouditor/voc"
 	"github.com/google/uuid"
@@ -44,6 +46,7 @@ import (
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/cam/internal/protobuf"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/cam/service"
 	. "gitlab.com/gaia-x/data-infrastructure-federation-services/cam/service/collection"
+	awsstrct "gitlab.com/gaia-x/data-infrastructure-federation-services/cam/service/collection/workload/aws/strct"
 	"gitlab.com/gaia-x/data-infrastructure-federation-services/cam/service/collection/workload/openstack"
 	openstackstrct "gitlab.com/gaia-x/data-infrastructure-federation-services/cam/service/collection/workload/openstack/strct"
 )
@@ -76,6 +79,7 @@ type Server struct {
 type providerConfiguration struct {
 	kubernetes *kubernetes.Clientset
 	openstack  *openstack.AuthOptions
+	aws        *aws.Client
 }
 
 // WithOAuth2Authorizer is an option to use an OAuth 2.0 authorizer
@@ -243,6 +247,15 @@ func (srv *Server) addProviderConfig(req *collection.StartCollectingRequest, con
 		return nil
 	}
 
+	// Set ServiceConfiguration for AWS
+	if aws := conf.Aws; aws != nil {
+		err = srv.awsConfig(aws, req.ServiceId)
+		if err != nil {
+			return fmt.Errorf("%s: %w", collection.ErrInvalidAWSServiceConfiguration, err)
+		}
+		return nil
+	}
+
 	return collection.ErrMissingServiceConfiguration
 
 }
@@ -294,6 +307,36 @@ func (srv *Server) openstackConfig(value *structpb.Value, serviceId string) erro
 
 }
 
+// awsConfig stores the AWS configuration
+func (srv *Server) awsConfig(value *structpb.Value, serviceId string) error {
+	// Get config from protobuf value
+	strct, err := awsstrct.ToConfig(value)
+	if err != nil {
+		return collection.ErrConversionProtobufToAuthOptions
+	}
+	// This is a little hack but should work. aws.NewClient() gets configured
+	// from the environment variables, so we just set it here.
+	os.Setenv("AWS_DEFAULT_REGION", strct.Region)
+	os.Setenv("AWS_ACCESS_KEY_ID", strct.AccessKeyID)
+	os.Setenv("AWS_SECRET_ACCESS_KEY", strct.SecretAccessKey)
+
+	client, err := aws.NewClient()
+	if err != nil {
+		return fmt.Errorf("could not create AWS client: %w", err)
+	}
+
+	// Store AWS config to the specific serviceID
+	configValue := providerConfiguration{
+		aws: client,
+	}
+	srv.providerConfigsMutex.Lock()
+	srv.providerConfigs[serviceId] = configValue
+	srv.providerConfigsMutex.Unlock()
+
+	return nil
+
+}
+
 // setDiscoverer sets discoverer for serviceID
 func (srv *Server) setDiscoverer(serviceID string) (discoverer []clapidiscovery.Discoverer) {
 	// Add Kubernetes discoverer for compute and storage
@@ -310,6 +353,14 @@ func (srv *Server) setDiscoverer(serviceID string) (discoverer []clapidiscovery.
 		return
 	}
 
+	// Add Openstack discoverer for compute and storage
+	if srv.providerConfigs[serviceID].aws != nil {
+		discoverer = append(discoverer, aws.NewAwsStorageDiscovery(srv.providerConfigs[serviceID].aws))
+		discoverer = append(discoverer, openstack.NewStorageDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)), openstack.NewComputeDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)))
+
+		return
+	}
+
 	return
 }
 
-- 
GitLab


From 13a85f357db75386b833bea9acb1350065095359 Mon Sep 17 00:00:00 2001
From: Christian Banse <oxisto@aybaze.com>
Date: Sun, 28 Aug 2022 16:01:15 +0200
Subject: [PATCH 2/3] Added empty check

---
 service/collection/workload/server.go | 30 +++++++++++++--------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/service/collection/workload/server.go b/service/collection/workload/server.go
index aab93e6b..da122115 100644
--- a/service/collection/workload/server.go
+++ b/service/collection/workload/server.go
@@ -229,35 +229,30 @@ func (srv *Server) addProviderConfig(req *collection.StartCollectingRequest, con
 	}
 
 	// Set ServiceConfiguration for Kubernetes
-	if k := conf.Kubernetes; k != nil {
+	if k := conf.Kubernetes; k != nil && !isEmpty(k) {
 		err = srv.kubeConfig(k, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidKubernetesServiceConfiguration, err)
 		}
-		return nil
 	}
 
 	// Set ServiceConfiguration for OpenStack
-	if os := conf.Openstack; os != nil {
+	if os := conf.Openstack; os != nil && !isEmpty(os) {
 		err := srv.openstackConfig(os, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidOpenstackServiceConfiguration, err)
 		}
-
-		return nil
 	}
 
 	// Set ServiceConfiguration for AWS
-	if aws := conf.Aws; aws != nil {
+	if aws := conf.Aws; aws != nil && !isEmpty(aws) {
 		err = srv.awsConfig(aws, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidAWSServiceConfiguration, err)
 		}
-		return nil
 	}
 
-	return collection.ErrMissingServiceConfiguration
-
+	return nil
 }
 
 // kubeConfig stores the Kubernetes configuration
@@ -342,28 +337,31 @@ func (srv *Server) setDiscoverer(serviceID string) (discoverer []clapidiscovery.
 	// Add Kubernetes discoverer for compute and storage
 	if srv.providerConfigs[serviceID].kubernetes != nil {
 		discoverer = append(discoverer, k8s.NewKubernetesComputeDiscovery(srv.providerConfigs[serviceID].kubernetes), k8s.NewKubernetesNetworkDiscovery(srv.providerConfigs[serviceID].kubernetes))
-
-		return
 	}
 
 	// Add Openstack discoverer for compute and storage
 	if srv.providerConfigs[serviceID].openstack != nil {
 		discoverer = append(discoverer, openstack.NewStorageDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)), openstack.NewComputeDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)))
-
-		return
 	}
 
 	// Add Openstack discoverer for compute and storage
 	if srv.providerConfigs[serviceID].aws != nil {
 		discoverer = append(discoverer, aws.NewAwsStorageDiscovery(srv.providerConfigs[serviceID].aws))
-		discoverer = append(discoverer, openstack.NewStorageDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)), openstack.NewComputeDiscovery(openstack.WithAuthOpts(srv.providerConfigs[serviceID].openstack)))
-
-		return
 	}
 
 	return
 }
 
+func isEmpty(value *structpb.Value) bool {
+	// Check, if it is an empty map, which means that its not configured. A little bit of a nasty workaround
+	strct := value.GetStructValue()
+	if len(strct.Fields) == 0 {
+		return true
+	}
+
+	return false
+}
+
 // Not used now
 //func validator(req *collection.StartCollectingRequest) (conf *collection.ServiceConfiguration_WorkloadSecurityConfig, err error) {
 //	if req.Configuration.CollectionModule != collection.ServiceConfiguration_WORKLOAD_CONFIGURATION {
-- 
GitLab


From d74c118515c82d2c8aace18e29fd24867aedebc9 Mon Sep 17 00:00:00 2001
From: Christian Banse <oxisto@aybaze.com>
Date: Sun, 28 Aug 2022 18:00:48 +0200
Subject: [PATCH 3/3] Fixed failing test

---
 service/collection/workload/server.go | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/service/collection/workload/server.go b/service/collection/workload/server.go
index da122115..485cccae 100644
--- a/service/collection/workload/server.go
+++ b/service/collection/workload/server.go
@@ -229,7 +229,7 @@ func (srv *Server) addProviderConfig(req *collection.StartCollectingRequest, con
 	}
 
 	// Set ServiceConfiguration for Kubernetes
-	if k := conf.Kubernetes; k != nil && !isEmpty(k) {
+	if k := conf.Kubernetes; !isEmpty(k) {
 		err = srv.kubeConfig(k, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidKubernetesServiceConfiguration, err)
@@ -237,7 +237,7 @@ func (srv *Server) addProviderConfig(req *collection.StartCollectingRequest, con
 	}
 
 	// Set ServiceConfiguration for OpenStack
-	if os := conf.Openstack; os != nil && !isEmpty(os) {
+	if os := conf.Openstack; !isEmpty(os) {
 		err := srv.openstackConfig(os, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidOpenstackServiceConfiguration, err)
@@ -245,7 +245,7 @@ func (srv *Server) addProviderConfig(req *collection.StartCollectingRequest, con
 	}
 
 	// Set ServiceConfiguration for AWS
-	if aws := conf.Aws; aws != nil && !isEmpty(aws) {
+	if aws := conf.Aws; !isEmpty(aws) {
 		err = srv.awsConfig(aws, req.ServiceId)
 		if err != nil {
 			return fmt.Errorf("%s: %w", collection.ErrInvalidAWSServiceConfiguration, err)
@@ -353,9 +353,14 @@ func (srv *Server) setDiscoverer(serviceID string) (discoverer []clapidiscovery.
 }
 
 func isEmpty(value *structpb.Value) bool {
+	// If value is nil, its definitly empty
+	if value == nil {
+		return true
+	}
+
 	// Check, if it is an empty map, which means that its not configured. A little bit of a nasty workaround
 	strct := value.GetStructValue()
-	if len(strct.Fields) == 0 {
+	if strct != nil && len(strct.Fields) == 0 {
 		return true
 	}
 
-- 
GitLab