diff --git a/bazel/toolchains/go_module_deps.bzl b/bazel/toolchains/go_module_deps.bzl index bbc46f276..2917c3ac7 100644 --- a/bazel/toolchains/go_module_deps.bzl +++ b/bazel/toolchains/go_module_deps.bzl @@ -343,14 +343,6 @@ def go_dependencies(): sum = "h1:xKbFXea2CIF/Wskauz1TMr//wZ6FyzEafMdSBIQqn80=", version = "v1.32.6", ) - go_repository( - name = "com_github_aws_aws_sdk_go_v2_service_cloudwatchlogs", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs", - sum = "h1:9apthAVGtCrw6LkswOcRpa1fMWur+7cGqO0yR65qsZM=", - version = "v1.30.2", - ) go_repository( name = "com_github_aws_aws_sdk_go_v2_service_ec2", build_file_generation = "on", @@ -511,14 +503,6 @@ def go_dependencies(): sum = "h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=", version = "v0.7.1", ) - go_repository( - name = "com_github_azure_azure_sdk_for_go_sdk_resourcemanager_applicationinsights_armapplicationinsights", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights", - sum = "h1:hBrFatNIiVAwDb5GzMLjpkQ6l2/waFSvBWMBWZRH8WI=", - version = "v1.1.1", - ) go_repository( name = "com_github_azure_azure_sdk_for_go_sdk_resourcemanager_compute_armcompute_v5", build_file_generation = "on", @@ -3603,14 +3587,6 @@ def go_dependencies(): sum = "h1:280wsy40IC9M9q1uPGcLBwXpcTQDtoGwVt+BNoITxIw=", version = "v0.4.0", ) - go_repository( - name = "com_github_microsoft_applicationinsights_go", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "github.com/microsoft/ApplicationInsights-Go", - sum = "h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY=", - version = "v0.4.4", - ) go_repository( name = "com_github_microsoft_go_winio", build_file_generation = "on", @@ -3939,14 +3915,6 @@ def go_dependencies(): sum = "h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=", version = "v1.2.8", ) - go_repository( - name = "com_github_onsi_ginkgo", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "github.com/onsi/ginkgo", - sum = "h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=", - version = "v1.8.0", - ) go_repository( name = "com_github_onsi_ginkgo_v2", build_file_generation = "on", @@ -4731,14 +4699,6 @@ def go_dependencies(): sum = "h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=", version = "v2.3.1", ) - go_repository( - name = "com_github_tedsuo_ifrit", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "github.com/tedsuo/ifrit", - sum = "h1:LUUe4cdABGrIJAhl1P1ZpWY76AwukVszFdwkVFVLwIk=", - version = "v0.0.0-20180802180643-bea94bb476cc", - ) go_repository( name = "com_github_theupdateframework_go_tuf", build_file_generation = "on", @@ -6872,14 +6832,6 @@ def go_dependencies(): sum = "h1:Z96pB6DkSb7F3Y3BBnJeOZH2gazyMTWlvecSD4vDqfk=", version = "v0.0.7", ) - go_repository( - name = "org_cloudfoundry_code_clock", - build_file_generation = "on", - build_file_proto_mode = "disable_global", - importpath = "code.cloudfoundry.org/clock", - sum = "h1:5eeuG0BHx1+DHeT3AP+ISKZ2ht1UjGhm581ljqYpVeQ=", - version = "v0.0.0-20180518195852-02e53af36e6c", - ) go_repository( name = "org_golang_google_api", build_file_generation = "on", diff --git a/bootstrapper/cmd/bootstrapper/BUILD.bazel b/bootstrapper/cmd/bootstrapper/BUILD.bazel index 628fea394..da8d4d9c2 100644 --- a/bootstrapper/cmd/bootstrapper/BUILD.bazel +++ b/bootstrapper/cmd/bootstrapper/BUILD.bazel @@ -20,7 +20,6 @@ go_library( "//bootstrapper/internal/kubernetes", "//bootstrapper/internal/kubernetes/k8sapi", "//bootstrapper/internal/kubernetes/kubewaiter", - "//bootstrapper/internal/logging", "//bootstrapper/internal/nodelock", "//internal/atls", "//internal/attestation/choose", diff --git a/bootstrapper/cmd/bootstrapper/main.go b/bootstrapper/cmd/bootstrapper/main.go index 670b063b6..efb010ea1 100644 --- a/bootstrapper/cmd/bootstrapper/main.go +++ b/bootstrapper/cmd/bootstrapper/main.go @@ -19,7 +19,6 @@ import ( "github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes" "github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/k8sapi" "github.com/edgelesssys/constellation/v2/bootstrapper/internal/kubernetes/kubewaiter" - "github.com/edgelesssys/constellation/v2/bootstrapper/internal/logging" "github.com/edgelesssys/constellation/v2/internal/attestation/choose" "github.com/edgelesssys/constellation/v2/internal/attestation/simulator" "github.com/edgelesssys/constellation/v2/internal/attestation/tdx" @@ -62,7 +61,6 @@ func main() { bindPort := strconv.Itoa(constants.BootstrapperPort) var clusterInitJoiner clusterInitJoiner var metadataAPI metadataAPI - var cloudLogger logging.CloudLogger var openDevice vtpm.TPMOpenFunc var fs afero.Fs @@ -83,11 +81,6 @@ func main() { } metadataAPI = metadata - cloudLogger, err = awscloud.NewLogger(ctx) - if err != nil { - log.With(zap.Error(err)).Fatalf("Failed to set up cloud logger") - } - clusterInitJoiner = kubernetes.New( "aws", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.NewUninitialized(), metadata, &kubewaiter.CloudKubeAPIWaiter{}, @@ -102,11 +95,6 @@ func main() { } defer metadata.Close() - cloudLogger, err = gcpcloud.NewLogger(ctx, "constellation-boot-log") - if err != nil { - log.With(zap.Error(err)).Fatalf("Failed to set up cloud logger") - } - metadataAPI = metadata clusterInitJoiner = kubernetes.New( "gcp", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.NewUninitialized(), @@ -120,10 +108,7 @@ func main() { if err != nil { log.With(zap.Error(err)).Fatalf("Failed to create Azure metadata client") } - cloudLogger, err = azurecloud.NewLogger(ctx) - if err != nil { - log.With(zap.Error(err)).Fatalf("Failed to set up cloud logger") - } + if err := metadata.PrepareControlPlaneNode(ctx, log); err != nil { log.With(zap.Error(err)).Fatalf("Failed to prepare Azure control plane node") } @@ -138,7 +123,6 @@ func main() { fs = afero.NewOsFs() case cloudprovider.QEMU: - cloudLogger = qemucloud.NewLogger() metadata := qemucloud.New() clusterInitJoiner = kubernetes.New( "qemu", k8sapi.NewKubernetesUtil(), &k8sapi.KubdeadmConfiguration{}, kubectl.NewUninitialized(), @@ -158,7 +142,6 @@ func main() { } fs = afero.NewOsFs() case cloudprovider.OpenStack: - cloudLogger = &logging.NopLogger{} metadata, err := openstackcloud.New(ctx) if err != nil { log.With(zap.Error(err)).Fatalf("Failed to create OpenStack metadata client") @@ -173,7 +156,6 @@ func main() { default: clusterInitJoiner = &clusterFake{} metadataAPI = &providerMetadataFake{} - cloudLogger = &logging.NopLogger{} var simulatedTPMCloser io.Closer openDevice, simulatedTPMCloser = simulator.NewSimulatedTPMOpenFunc() defer simulatedTPMCloser.Close() @@ -182,5 +164,5 @@ func main() { fileHandler := file.NewHandler(fs) - run(issuer, openDevice, fileHandler, clusterInitJoiner, metadataAPI, bindIP, bindPort, log, cloudLogger) + run(issuer, openDevice, fileHandler, clusterInitJoiner, metadataAPI, bindIP, bindPort, log) } diff --git a/bootstrapper/cmd/bootstrapper/run.go b/bootstrapper/cmd/bootstrapper/run.go index c036b5ba9..41630b6d5 100644 --- a/bootstrapper/cmd/bootstrapper/run.go +++ b/bootstrapper/cmd/bootstrapper/run.go @@ -14,7 +14,6 @@ import ( "github.com/edgelesssys/constellation/v2/bootstrapper/internal/diskencryption" "github.com/edgelesssys/constellation/v2/bootstrapper/internal/initserver" "github.com/edgelesssys/constellation/v2/bootstrapper/internal/joinclient" - "github.com/edgelesssys/constellation/v2/bootstrapper/internal/logging" "github.com/edgelesssys/constellation/v2/bootstrapper/internal/nodelock" "github.com/edgelesssys/constellation/v2/internal/atls" "github.com/edgelesssys/constellation/v2/internal/attestation/initialize" @@ -29,20 +28,14 @@ import ( func run(issuer atls.Issuer, openDevice vtpm.TPMOpenFunc, fileHandler file.Handler, kube clusterInitJoiner, metadata metadataAPI, bindIP, bindPort string, log *logger.Logger, - cloudLogger logging.CloudLogger, ) { - defer cloudLogger.Close() - log.With(zap.String("version", constants.BinaryVersion().String())).Infof("Starting bootstrapper") - cloudLogger.Disclose("bootstrapper started running...") uuid, err := getDiskUUID() if err != nil { log.With(zap.Error(err)).Errorf("Failed to get disk UUID") - cloudLogger.Disclose("Failed to get disk UUID") } else { log.Infof("Disk UUID: %s", uuid) - cloudLogger.Disclose("Disk UUID: " + uuid) } nodeBootstrapped, err := initialize.IsNodeBootstrapped(openDevice) @@ -77,7 +70,6 @@ func run(issuer atls.Issuer, openDevice vtpm.TPMOpenFunc, fileHandler file.Handl } log.Infof("bootstrapper done") - cloudLogger.Disclose("bootstrapper done") } func getDiskUUID() (string, error) { diff --git a/docs/docs/workflows/troubleshooting.md b/docs/docs/workflows/troubleshooting.md index 633053e0b..3c952dddc 100644 --- a/docs/docs/workflows/troubleshooting.md +++ b/docs/docs/workflows/troubleshooting.md @@ -95,49 +95,14 @@ check if the encountered [issue is known](https://github.com/edgelesssys/constel ## Diagnosing issues -### Cloud logging +### Logs -To provide information during early stages of a node's boot process, Constellation logs messages to the log systems of the cloud providers. Since these offerings **aren't** confidential, only generic information without any sensitive values is stored. This provides administrators with a high-level understanding of the current state of a node. +To get started on diagnosing issues with Constellation, it's often helpful to collect logs from nodes, pods, or other resources in the cluster. Most logs are available through Kubernetes' standard +[logging interfaces](https://kubernetes.io/docs/concepts/cluster-administration/logging/). -You can view this information in the following places: +To debug issues occurring at boot time of the nodes, you can use the serial console interface of the CSP while the machine boots to get a read-only view of the boot logs. - - - -1. In your Azure subscription find the Constellation resource group. -2. Inside the resource group find the Application Insights resource called `constellation-insights-*`. -3. On the left-hand side go to `Logs`, which is located in the section `Monitoring`. - - Close the Queries page if it pops up. -5. In the query text field type in `traces`, and click `Run`. - -To **find the disk UUIDs** use the following query: `traces | where message contains "Disk UUID"` - - - - -1. Select the project that hosts Constellation. -2. Go to the `Compute Engine` service. -3. On the right-hand side of a VM entry select `More Actions` (a stacked ellipsis) - - Select `View logs` - -To **find the disk UUIDs** use the following query: `resource.type="gce_instance" text_payload=~"Disk UUID:.*\n" logName=~".*/constellation-boot-log"` - -:::info - -Constellation uses the default bucket to store logs. Its [default retention period is 30 days](https://cloud.google.com/logging/quotas#logs_retention_periods). - -::: - - - - -1. Open [AWS CloudWatch](https://console.aws.amazon.com/cloudwatch/home) -2. Select [Log Groups](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups) -3. Select the log group that matches the name of your cluster. -4. Select the log stream for control or worker type nodes. - - - +Apart from that, Constellation also offers further [observability integrations](../architecture/observability.md). ### Node shell access diff --git a/go.mod b/go.mod index 2293dd92f..53c73b06f 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( cloud.google.com/go/compute v1.23.0 cloud.google.com/go/compute/metadata v0.2.3 cloud.google.com/go/kms v1.15.2 - cloud.google.com/go/logging v1.8.1 cloud.google.com/go/secretmanager v1.11.1 cloud.google.com/go/storage v1.31.0 dario.cat/mergo v1.0.0 @@ -52,11 +51,9 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights v1.1.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.0.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 - github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/aws/aws-sdk-go v1.44.297 github.com/aws/aws-sdk-go-v2 v1.24.1 github.com/aws/aws-sdk-go-v2/config v1.26.3 @@ -65,7 +62,6 @@ require ( github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.11 github.com/aws/aws-sdk-go-v2/service/autoscaling v1.36.7 github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.6 - github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.2 github.com/aws/aws-sdk-go-v2/service/ec2 v1.143.0 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.26.7 github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.19.7 @@ -109,8 +105,7 @@ require ( github.com/hashicorp/terraform-plugin-testing v1.6.0 github.com/hexops/gotextdiff v1.0.3 github.com/martinjungblut/go-cryptsetup v0.0.0-20220520180014-fd0874fd07a6 - github.com/mattn/go-isatty v0.0.19 - github.com/microsoft/ApplicationInsights-Go v0.4.4 + github.com/mattn/go-isatty v0.0.20 github.com/onsi/ginkgo/v2 v2.13.0 github.com/onsi/gomega v1.29.0 github.com/pkg/errors v0.9.1 @@ -161,8 +156,6 @@ require ( require ( cloud.google.com/go v0.110.8 // indirect cloud.google.com/go/iam v1.1.2 // indirect - cloud.google.com/go/longrunning v0.5.1 // indirect - code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect @@ -173,6 +166,7 @@ require ( github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect @@ -248,7 +242,6 @@ require ( github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect diff --git a/go.sum b/go.sum index 09998bb8e..e9a891235 100644 --- a/go.sum +++ b/go.sum @@ -35,10 +35,6 @@ cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4= cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/kms v1.15.2 h1:lh6qra6oC4AyWe5fUUUBe/S27k12OHAleOOOw6KakdE= cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w= -cloud.google.com/go/logging v1.8.1 h1:26skQWPeYhvIasWKm48+Eq7oUqdcdbwsCVwz5Ys0FvU= -cloud.google.com/go/logging v1.8.1/go.mod h1:TJjR+SimHwuC8MZ9cjByQulAMgni+RkXeI3wwctHJEI= -cloud.google.com/go/longrunning v0.5.1 h1:Fr7TXftcqTudoyRJa113hyaqlGdiBQkp0Gq7tErFDWI= -cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -53,8 +49,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.31.0 h1:+S3LjjEN2zZ+L5hOwj4+1OkGCsLVe0NzpXKQ1pSdTCI= cloud.google.com/go/storage v1.31.0/go.mod h1:81ams1PrhW16L4kF7qg+4mTq7SRs5HsbDTM0bWvrwJ0= -code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c h1:5eeuG0BHx1+DHeT3AP+ISKZ2ht1UjGhm581ljqYpVeQ= -code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -74,8 +68,6 @@ github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0 h1:xnO4sFyG8UH2 github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0/go.mod h1:XD3DIOOVgBCO03OleB1fHjgktVRFxlT++KwKgIOewdM= github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw= github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights v1.1.1 h1:hBrFatNIiVAwDb5GzMLjpkQ6l2/waFSvBWMBWZRH8WI= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights v1.1.1/go.mod h1:uxknLoFj+nBXpfGngz0B4ciNur04Y0EX4AREpy2GIvk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0 h1:Sg/D8VuUQ+bw+FOYJF+xRKcwizCOP13HL0Se8pWNBzE= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.1.0/go.mod h1:Kyqzdqq0XDoCm+o9aZ25wZBmBUBzPBzPAj1R5rYsT6I= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= @@ -189,8 +181,6 @@ github.com/aws/aws-sdk-go-v2/service/autoscaling v1.36.7 h1:Vy2KdIN8tGSKBhwvjbWQ github.com/aws/aws-sdk-go-v2/service/autoscaling v1.36.7/go.mod h1:D5vhsHh8cnUikp91klW0VIEGG/ygAWiUOmGZU+Q4iZ0= github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.6 h1:xKbFXea2CIF/Wskauz1TMr//wZ6FyzEafMdSBIQqn80= github.com/aws/aws-sdk-go-v2/service/cloudfront v1.32.6/go.mod h1:iB6PQSb3ULRrrlEiuFfVE318JiBOdk4k46BbuzrrgXc= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.2 h1:9apthAVGtCrw6LkswOcRpa1fMWur+7cGqO0yR65qsZM= -github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.30.2/go.mod h1:jZNaJEtn9TLi3pfxycLz79HVkKxP8ZdYm92iaNFgBsA= github.com/aws/aws-sdk-go-v2/service/ec2 v1.143.0 h1:ZAO4y7MSRqU74ZFCA+HC6Ek5fI7dsTdwJg88s72I/gE= github.com/aws/aws-sdk-go-v2/service/ec2 v1.143.0/go.mod h1:hIsHE0PaWAQakLCshKS7VKWMGXaqrAFp4m95s2W9E6c= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.26.7 h1:ystNRv96lPnlDFU/K3O4/erHR+kPaiDbDGi/192uXQ4= @@ -344,7 +334,6 @@ github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6 github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -467,9 +456,6 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= -github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -683,7 +669,6 @@ github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvz github.com/honeycombio/libhoney-go v1.16.0/go.mod h1:izP4fbREuZ3vqC4HlCAmPrcPT9gxyxejRjGtCYpmBn0= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -793,8 +778,6 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/microsoft/ApplicationInsights-Go v0.4.4 h1:G4+H9WNs6ygSCe6sUyxRc2U81TI5Es90b2t/MwX5KqY= -github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= @@ -845,11 +828,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -968,7 +948,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= github.com/theupdateframework/go-tuf v0.5.2 h1:habfDzTmpbzBLIFGWa2ZpVhYvFBoK0C1onC3a4zuPRA= github.com/theupdateframework/go-tuf v0.5.2/go.mod h1:SyMV5kg5n4uEclsyxXJZI2UxPFJNDc4Y+r7wv+MlvTA= github.com/thomasten/go-tpm v0.0.0-20230629092004-f43f8e2a59eb h1:840nUyrM9df2aLuzWuIkYx/DrUbX4KQZO6B9LD45aWo= @@ -1131,7 +1110,6 @@ golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1203,7 +1181,6 @@ golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1473,12 +1450,10 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/hack/qemu-metadata-api/server/server.go b/hack/qemu-metadata-api/server/server.go index c60bdae30..93d6f3a04 100644 --- a/hack/qemu-metadata-api/server/server.go +++ b/hack/qemu-metadata-api/server/server.go @@ -9,7 +9,6 @@ package server import ( "encoding/json" "fmt" - "io" "net" "net/http" "strings" @@ -44,7 +43,6 @@ func (s *Server) ListenAndServe(port string) error { mux := http.NewServeMux() mux.Handle("/self", http.HandlerFunc(s.listSelf)) mux.Handle("/peers", http.HandlerFunc(s.listPeers)) - mux.Handle("/log", http.HandlerFunc(s.postLog)) mux.Handle("/endpoint", http.HandlerFunc(s.getEndpoint)) mux.Handle("/initsecrethash", http.HandlerFunc(s.initSecretHash)) @@ -173,33 +171,6 @@ func (s *Server) getEndpoint(w http.ResponseWriter, r *http.Request) { http.Error(w, "No matching peer found", http.StatusNotFound) } -// postLog writes implements cloud-logging for QEMU instances. -func (s *Server) postLog(w http.ResponseWriter, r *http.Request) { - log := s.log.With(zap.String("peer", r.RemoteAddr)) - if r.Method != http.MethodPost { - log.With(zap.String("method", r.Method)).Errorf("Invalid method for /log") - http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) - return - } - - log.Infof("Serving POST request for /log") - - if r.Body == nil { - log.Errorf("Request body is empty") - http.Error(w, "Request body is empty", http.StatusBadRequest) - return - } - - msg, err := io.ReadAll(r.Body) - if err != nil { - log.With(zap.Error(err)).Errorf("Failed to read request body") - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - log.With(zap.String("message", string(msg))).Infof("Cloud-logging entry") -} - // listAll returns a list of all active peers. func (s *Server) listAll() ([]metadata.InstanceMetadata, error) { net, err := s.virt.LookupNetworkByName(s.network) diff --git a/hack/qemu-metadata-api/server/server_test.go b/hack/qemu-metadata-api/server/server_test.go index d9c78c2a5..3b04d214d 100644 --- a/hack/qemu-metadata-api/server/server_test.go +++ b/hack/qemu-metadata-api/server/server_test.go @@ -13,7 +13,6 @@ import ( "io" "net/http" "net/http/httptest" - "strings" "testing" "github.com/edgelesssys/constellation/v2/hack/qemu-metadata-api/virtwrapper" @@ -223,55 +222,6 @@ func TestListPeers(t *testing.T) { } } -func TestPostLog(t *testing.T) { - testCases := map[string]struct { - remoteAddr string - message io.Reader - method string - wantErr bool - }{ - "success": { - remoteAddr: "192.0.100.1:1234", - method: http.MethodPost, - message: strings.NewReader("test message"), - }, - "no body": { - remoteAddr: "192.0.100.1:1234", - method: http.MethodPost, - message: nil, - wantErr: true, - }, - "incorrect method": { - remoteAddr: "192.0.100.1:1234", - method: http.MethodGet, - message: strings.NewReader("test message"), - wantErr: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - server := New(logger.NewTest(t), "test", "initSecretHash", &stubConnect{}) - - req, err := http.NewRequestWithContext(context.Background(), tc.method, "http://192.0.0.1/logs", tc.message) - require.NoError(err) - req.RemoteAddr = tc.remoteAddr - - w := httptest.NewRecorder() - server.postLog(w, req) - - if tc.wantErr { - assert.NotEqual(http.StatusOK, w.Code) - } else { - assert.Equal(http.StatusOK, w.Code) - } - }) - } -} - func TestInitSecretHash(t *testing.T) { defaultConnect := &stubConnect{ network: newStubNetwork([]virtwrapper.NetworkDHCPLease{ diff --git a/internal/cloud/aws/BUILD.bazel b/internal/cloud/aws/BUILD.bazel index b3ead651d..808e474ab 100644 --- a/internal/cloud/aws/BUILD.bazel +++ b/internal/cloud/aws/BUILD.bazel @@ -3,10 +3,7 @@ load("//bazel/go:go_test.bzl", "go_test") go_library( name = "aws", - srcs = [ - "aws.go", - "logger.go", - ], + srcs = ["aws.go"], importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/aws", visibility = ["//:__subpackages__"], deps = [ @@ -17,24 +14,18 @@ go_library( "@com_github_aws_aws_sdk_go_v2//aws", "@com_github_aws_aws_sdk_go_v2_config//:config", "@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds", - "@com_github_aws_aws_sdk_go_v2_service_cloudwatchlogs//:cloudwatchlogs", - "@com_github_aws_aws_sdk_go_v2_service_cloudwatchlogs//types", "@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2", "@com_github_aws_aws_sdk_go_v2_service_ec2//types", "@com_github_aws_aws_sdk_go_v2_service_elasticloadbalancingv2//:elasticloadbalancingv2", "@com_github_aws_aws_sdk_go_v2_service_elasticloadbalancingv2//types", "@com_github_aws_aws_sdk_go_v2_service_resourcegroupstaggingapi//:resourcegroupstaggingapi", "@com_github_aws_aws_sdk_go_v2_service_resourcegroupstaggingapi//types", - "@io_k8s_utils//clock", ], ) go_test( name = "aws_test", - srcs = [ - "aws_test.go", - "logger_test.go", - ], + srcs = ["aws_test.go"], embed = [":aws"], deps = [ "//internal/cloud", @@ -42,8 +33,6 @@ go_test( "//internal/role", "@com_github_aws_aws_sdk_go_v2//aws", "@com_github_aws_aws_sdk_go_v2_feature_ec2_imds//:imds", - "@com_github_aws_aws_sdk_go_v2_service_cloudwatchlogs//:cloudwatchlogs", - "@com_github_aws_aws_sdk_go_v2_service_cloudwatchlogs//types", "@com_github_aws_aws_sdk_go_v2_service_ec2//:ec2", "@com_github_aws_aws_sdk_go_v2_service_ec2//types", "@com_github_aws_aws_sdk_go_v2_service_elasticloadbalancingv2//:elasticloadbalancingv2", @@ -51,8 +40,5 @@ go_test( "@com_github_aws_aws_sdk_go_v2_service_resourcegroupstaggingapi//:resourcegroupstaggingapi", "@com_github_aws_aws_sdk_go_v2_service_resourcegroupstaggingapi//types", "@com_github_stretchr_testify//assert", - "@com_github_stretchr_testify//require", - "@io_k8s_utils//clock/testing", - "@org_uber_go_goleak//:goleak", ], ) diff --git a/internal/cloud/aws/aws.go b/internal/cloud/aws/aws.go index f788aed03..bfa1d0b54 100644 --- a/internal/cloud/aws/aws.go +++ b/internal/cloud/aws/aws.go @@ -36,10 +36,6 @@ import ( "github.com/edgelesssys/constellation/v2/internal/role" ) -const ( - tagName = "Name" -) - type resourceAPI interface { GetResources(context.Context, *resourcegroupstaggingapi.GetResourcesInput, ...func(*resourcegroupstaggingapi.Options)) (*resourcegroupstaggingapi.GetResourcesOutput, error) } diff --git a/internal/cloud/aws/logger.go b/internal/cloud/aws/logger.go deleted file mode 100644 index cbe0893de..000000000 --- a/internal/cloud/aws/logger.go +++ /dev/null @@ -1,228 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package aws - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - logs "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" - "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" - "github.com/aws/aws-sdk-go-v2/service/ec2" - "github.com/edgelesssys/constellation/v2/internal/cloud" - "k8s.io/utils/clock" -) - -// Logger is a Cloud Logger for AWS. -// Log messages are collected and periodically flushed to AWS Cloudwatch Logs. -type Logger struct { - api logAPI - - ec2API ec2API - imdsAPI imdsAPI - - groupName string - streamName string - - logs []types.InputLogEvent - sequenceToken *string - - mux sync.Mutex - interval time.Duration - clock clock.WithTicker - wg sync.WaitGroup - stopCh chan struct{} -} - -// NewLogger creates a new Cloud Logger for AWS. -func NewLogger(ctx context.Context) (*Logger, error) { - cfg, err := config.LoadDefaultConfig(ctx, config.WithEC2IMDSRegion()) - if err != nil { - return nil, err - } - client := logs.NewFromConfig(cfg) - - l := &Logger{ - api: client, - ec2API: ec2.NewFromConfig(cfg), - imdsAPI: imds.NewFromConfig(cfg), - interval: time.Second, - clock: clock.RealClock{}, - wg: sync.WaitGroup{}, - stopCh: make(chan struct{}, 1), - } - - if err := l.createStream(ctx); err != nil { - return nil, err - } - - l.flushLoop() - - return l, nil -} - -// Disclose adds a message to the log queue. -// The messages are flushed periodically to AWS Cloudwatch Logs. -func (l *Logger) Disclose(msg string) { - l.mux.Lock() - defer l.mux.Unlock() - l.logs = append(l.logs, types.InputLogEvent{ - Message: aws.String(msg), - Timestamp: aws.Int64(l.clock.Now().UnixMilli()), - }) -} - -// Close flushes the logs a final time and stops the flush loop. -func (l *Logger) Close() error { - l.stopCh <- struct{}{} - l.wg.Wait() - return l.flushLogs() -} - -// flushLogs flushes the aggregated log messages to AWS Cloudwatch Logs. -func (l *Logger) flushLogs() error { - // make sure only one flush operation is running at a time - l.mux.Lock() - defer l.mux.Unlock() - - if len(l.logs) == 0 { - return nil // no logs to flush - } - - ctx := context.Background() - logRequest := &logs.PutLogEventsInput{ - LogEvents: l.logs, - LogGroupName: &l.groupName, - LogStreamName: &l.streamName, - SequenceToken: l.sequenceToken, - } - - for res, err := l.api.PutLogEvents(ctx, logRequest); ; res, err = l.api.PutLogEvents(ctx, logRequest) { - if err == nil { - l.sequenceToken = res.NextSequenceToken - l.logs = nil - return nil - } - // If the flush operation was called on a pre-existing stream, - // or another operation sent logs to the same stream, - // the sequence token may not be set correctly. - // We can retrieve the correct sequence token from the error message. - var sequenceErr *types.InvalidSequenceTokenException - if !errors.As(err, &sequenceErr) { - return err - } - logRequest.SequenceToken = sequenceErr.ExpectedSequenceToken - } -} - -// flushLoop periodically flushes the logs to AWS Cloudwatch Logs. -func (l *Logger) flushLoop() { - l.wg.Add(1) - ticker := l.clock.NewTicker(l.interval) - - go func() { - defer l.wg.Done() - defer ticker.Stop() - - for { - _ = l.flushLogs() - select { - case <-ticker.C(): - case <-l.stopCh: - return - } - } - }() -} - -// createStream creates a new log stream in AWS Cloudwatch Logs. -func (l *Logger) createStream(ctx context.Context) error { - name, uid, err := l.getNameAndUID(ctx) - if err != nil { - return err - } - l.streamName = name - - // find log group with matching Constellation UID - describeInput := &logs.DescribeLogGroupsInput{} - for res, err := l.api.DescribeLogGroups(ctx, describeInput); ; res, err = l.api.DescribeLogGroups(ctx, describeInput) { - if err != nil { - return err - } - - for _, group := range res.LogGroups { - tags, err := l.api.ListTagsLogGroup(ctx, &logs.ListTagsLogGroupInput{LogGroupName: group.LogGroupName}) - if err != nil { - continue // we may not have permission to read the tags of a log group outside the Constellation scope - } - if tags.Tags[cloud.TagUID] == uid { - l.groupName = *group.LogGroupName - res.NextToken = nil // stop pagination - break - } - } - if res.NextToken == nil { - break - } - describeInput.NextToken = res.NextToken - } - if l.groupName == "" { - return fmt.Errorf("failed to find log group for UID %s", uid) - } - - // create or use existing log stream - if _, err := l.api.CreateLogStream(ctx, &logs.CreateLogStreamInput{ - LogGroupName: &l.groupName, - LogStreamName: &l.streamName, - }); err != nil { - // Ignore error if the stream already exists - var createErr *types.ResourceAlreadyExistsException - if !errors.As(err, &createErr) { - return err - } - } - - return nil -} - -func (l *Logger) getNameAndUID(ctx context.Context) (string, string, error) { - identity, err := l.imdsAPI.GetInstanceIdentityDocument(ctx, &imds.GetInstanceIdentityDocumentInput{}) - if err != nil { - return "", "", fmt.Errorf("retrieving instance identity: %w", err) - } - - out, err := l.ec2API.DescribeInstances(ctx, &ec2.DescribeInstancesInput{ - InstanceIds: []string{identity.InstanceID}, - }) - if err != nil { - return "", "", fmt.Errorf("descibing instances: %w", err) - } - - if len(out.Reservations) != 1 || len(out.Reservations[0].Instances) != 1 { - return "", "", fmt.Errorf("expected 1 instance, got %d", len(out.Reservations[0].Instances)) - } - - uid, err := findTag(out.Reservations[0].Instances[0].Tags, cloud.TagUID) - if err != nil { - return "", "", fmt.Errorf("finding tag %s: %w", cloud.TagUID, err) - } - - return identity.InstanceID, uid, err -} - -type logAPI interface { - CreateLogStream(context.Context, *logs.CreateLogStreamInput, ...func(*logs.Options)) (*logs.CreateLogStreamOutput, error) - DescribeLogGroups(context.Context, *logs.DescribeLogGroupsInput, ...func(*logs.Options)) (*logs.DescribeLogGroupsOutput, error) - ListTagsLogGroup(context.Context, *logs.ListTagsLogGroupInput, ...func(*logs.Options)) (*logs.ListTagsLogGroupOutput, error) - PutLogEvents(context.Context, *logs.PutLogEventsInput, ...func(*logs.Options)) (*logs.PutLogEventsOutput, error) -} diff --git a/internal/cloud/aws/logger_test.go b/internal/cloud/aws/logger_test.go deleted file mode 100644 index 9e55a4dec..000000000 --- a/internal/cloud/aws/logger_test.go +++ /dev/null @@ -1,554 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package aws - -import ( - "context" - "errors" - "strconv" - "sync" - "testing" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - logs "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs" - cloudwatchtypes "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" - "github.com/aws/aws-sdk-go-v2/service/ec2" - ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" - "github.com/edgelesssys/constellation/v2/internal/cloud" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.uber.org/goleak" - testclock "k8s.io/utils/clock/testing" -) - -func TestMain(m *testing.M) { - goleak.VerifyTestMain(m, goleak.IgnoreAnyFunction("github.com/bazelbuild/rules_go/go/tools/bzltestutil.RegisterTimeoutHandler.func1")) -} - -func TestCreateStream(t *testing.T) { - someErr := errors.New("failed") - - testCases := map[string]struct { - imdsAPI *stubIMDS - ec2API *stubEC2 - logs *stubLogs - wantGroup string - wantStream string - wantErr bool - }{ - "success new stream minimal": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - {LogGroupName: aws.String("test-group")}, - }, - }, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - }, - wantStream: "test-instance", - wantGroup: "test-group", - }, - "success one group of many": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - { - LogGroupName: aws.String("random-group"), - }, - { - LogGroupName: aws.String("other-group"), - }, - }, - NextToken: aws.String("next"), - }, - describeRes2: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - { - LogGroupName: aws.String("another-group"), - }, - { - LogGroupName: aws.String("test-group"), - }, - }, - }, - listTags: map[string]map[string]string{ - "random-group": { - "some-tag": "random-tag", - }, - "other-group": { - cloud.TagUID: "other-uid", - }, - "another-group": { - "some-tag": "uid", - }, - "test-group": { - cloud.TagUID: "uid", - }, - }, - }, - wantStream: "test-instance", - wantGroup: "test-group", - }, - "success stream exists": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - {LogGroupName: aws.String("test-group")}, - }, - }, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - createErr: &cloudwatchtypes.ResourceAlreadyExistsException{}, - }, - wantStream: "test-instance", - wantGroup: "test-group", - }, - "create stream error": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - {LogGroupName: aws.String("test-group")}, - }, - }, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - createErr: someErr, - }, - wantErr: true, - }, - "missing uid tag": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - {LogGroupName: aws.String("test-group")}, - }, - }, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - }, - wantErr: true, - }, - "missing identity document": { - imdsAPI: &stubIMDS{ - getInstanceIdentityDocumentErr: assert.AnError, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{ - LogGroups: []cloudwatchtypes.LogGroup{ - {LogGroupName: aws.String("test-group")}, - }, - }, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - }, - wantErr: true, - }, - "describe groups error": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeErr: someErr, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - }, - wantErr: true, - }, - "no matching groups": { - imdsAPI: &stubIMDS{ - instanceDocumentResp: &imds.GetInstanceIdentityDocumentOutput{ - InstanceIdentityDocument: imds.InstanceIdentityDocument{ - InstanceID: "test-instance", - }, - }, - }, - ec2API: &stubEC2{ - selfInstance: &ec2.DescribeInstancesOutput{ - Reservations: []ec2types.Reservation{ - { - Instances: []ec2types.Instance{ - { - InstanceId: aws.String("test-instance"), - Tags: []ec2types.Tag{ - { - Key: aws.String(tagName), - Value: aws.String("test-instance"), - }, - { - Key: aws.String(cloud.TagUID), - Value: aws.String("uid"), - }, - }, - }, - }, - }, - }, - }, - }, - logs: &stubLogs{ - describeRes1: &logs.DescribeLogGroupsOutput{}, - listTags: map[string]map[string]string{"test-group": {cloud.TagUID: "uid"}}, - }, - wantErr: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - assert := assert.New(t) - l := &Logger{ - api: tc.logs, - imdsAPI: tc.imdsAPI, - ec2API: tc.ec2API, - } - - err := l.createStream(context.Background()) - if tc.wantErr { - assert.Error(err) - return - } - - assert.NoError(err) - assert.Equal(tc.wantGroup, l.groupName) - assert.Equal(tc.wantStream, l.streamName) - }) - } -} - -func TestLogging(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - logAPI := &stubLogs{} - - l := &Logger{ - api: logAPI, - interval: 1 * time.Millisecond, - clock: testclock.NewFakeClock(time.Time{}), - } - - l.Disclose("msg") - l.Disclose("msg") - // no logs until we flush to the API - assert.Len(logAPI.logs, 0) - - // flush - require.NoError(l.flushLogs()) - assert.Len(logAPI.logs, 2) - - // flushing doesn't do anything if there are no logs - require.NoError(l.flushLogs()) - assert.Len(logAPI.logs, 2) - - // if we flush with an incorrect sequence token, - // we should get a new sequence token and retry - logAPI.logSequenceToken = 15 - l.Disclose("msg") - require.NoError(l.flushLogs()) - assert.Len(logAPI.logs, 3) - - logAPI.putErr = errors.New("failed") - l.Disclose("msg") - assert.Error(l.flushLogs()) -} - -func TestFlushLoop(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - logAPI := &stubLogs{} - clock := testclock.NewFakeClock(time.Time{}) - - l := &Logger{ - api: logAPI, - interval: 1 * time.Second, - clock: clock, - stopCh: make(chan struct{}, 1), - } - - l.Disclose("msg") - l.Disclose("msg") - - l.flushLoop() - clock.Step(1 * time.Second) - require.NoError(l.Close()) - assert.Len(logAPI.logs, 2) -} - -func TestConcurrency(t *testing.T) { - assert := assert.New(t) - require := require.New(t) - - l := &Logger{ - api: &stubLogs{}, - interval: 1 * time.Second, - clock: testclock.NewFakeClock(time.Time{}), - stopCh: make(chan struct{}, 1), - } - var wg sync.WaitGroup - - wg.Add(100) - for i := 0; i < 100; i++ { - go func() { - defer wg.Done() - l.Disclose("msg") - }() - } - - wg.Wait() - assert.Len(l.logs, 100) - require.NoError(l.flushLogs()) - assert.Len(l.logs, 0) - - wg.Add(100) - for i := 0; i < 100; i++ { - go func() { - defer wg.Done() - l.Disclose("msg") - require.NoError(l.flushLogs()) - }() - } - wg.Wait() - assert.Len(l.logs, 0) -} - -type stubLogs struct { - createErr error - describeErr error - describeRes1 *logs.DescribeLogGroupsOutput - describeRes2 *logs.DescribeLogGroupsOutput - listTagsErr error - listTags map[string]map[string]string - putErr error - logSequenceToken int - logs []cloudwatchtypes.InputLogEvent -} - -func (s *stubLogs) CreateLogStream(context.Context, *logs.CreateLogStreamInput, ...func(*logs.Options)) (*logs.CreateLogStreamOutput, error) { - return nil, s.createErr -} - -func (s *stubLogs) DescribeLogGroups(_ context.Context, in *logs.DescribeLogGroupsInput, _ ...func(*logs.Options)) (*logs.DescribeLogGroupsOutput, error) { - if in.NextToken == nil { - return s.describeRes1, s.describeErr - } - return s.describeRes2, s.describeErr -} - -func (s *stubLogs) ListTagsLogGroup(_ context.Context, in *logs.ListTagsLogGroupInput, _ ...func(*logs.Options)) (*logs.ListTagsLogGroupOutput, error) { - return &logs.ListTagsLogGroupOutput{Tags: s.listTags[*in.LogGroupName]}, s.listTagsErr -} - -func (s *stubLogs) PutLogEvents(_ context.Context, in *logs.PutLogEventsInput, _ ...func(*logs.Options)) (*logs.PutLogEventsOutput, error) { - if s.putErr != nil { - return nil, s.putErr - } - if in.SequenceToken == nil || *in.SequenceToken == "" { - in.SequenceToken = aws.String("0") - } - gotSeq, err := strconv.Atoi(*in.SequenceToken) - if err != nil { - return nil, err - } - if gotSeq != s.logSequenceToken { - return nil, &cloudwatchtypes.InvalidSequenceTokenException{ExpectedSequenceToken: aws.String(strconv.Itoa(s.logSequenceToken))} - } - - s.logs = append(s.logs, in.LogEvents...) - s.logSequenceToken++ - - return &logs.PutLogEventsOutput{NextSequenceToken: aws.String(strconv.Itoa(s.logSequenceToken))}, nil -} diff --git a/internal/cloud/azure/BUILD.bazel b/internal/cloud/azure/BUILD.bazel index 7ed700701..efbca7f59 100644 --- a/internal/cloud/azure/BUILD.bazel +++ b/internal/cloud/azure/BUILD.bazel @@ -7,7 +7,6 @@ go_library( "azure.go", "imds.go", "interface.go", - "logger.go", ], importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/azure", visibility = ["//:__subpackages__"], @@ -20,10 +19,8 @@ go_library( "//internal/role", "@com_github_azure_azure_sdk_for_go_sdk_azcore//runtime", "@com_github_azure_azure_sdk_for_go_sdk_azidentity//:azidentity", - "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_applicationinsights_armapplicationinsights//:armapplicationinsights", "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_compute_armcompute_v5//:armcompute", "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_network_armnetwork_v5//:armnetwork", - "@com_github_microsoft_applicationinsights_go//appinsights", "@io_k8s_kubernetes//pkg/util/iptables", "@io_k8s_utils//exec", "@org_uber_go_zap//:zap", @@ -35,7 +32,6 @@ go_test( srcs = [ "azure_test.go", "imds_test.go", - "logger_test.go", ], embed = [":azure"], deps = [ @@ -44,10 +40,8 @@ go_test( "//internal/role", "@com_github_azure_azure_sdk_for_go_sdk_azcore//runtime", "@com_github_azure_azure_sdk_for_go_sdk_azcore//to", - "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_applicationinsights_armapplicationinsights//:armapplicationinsights", "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_compute_armcompute_v5//:armcompute", "@com_github_azure_azure_sdk_for_go_sdk_resourcemanager_network_armnetwork_v5//:armnetwork", - "@com_github_azure_go_autorest_autorest_to//:to", "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", "@org_golang_google_grpc//test/bufconn", diff --git a/internal/cloud/azure/interface.go b/internal/cloud/azure/interface.go index 84386bb17..fc61e09b2 100644 --- a/internal/cloud/azure/interface.go +++ b/internal/cloud/azure/interface.go @@ -10,7 +10,6 @@ import ( "context" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5" ) @@ -74,9 +73,3 @@ type loadBalancerAPI interface { NewListPager(resourceGroupName string, options *armnetwork.LoadBalancersClientListOptions, ) *runtime.Pager[armnetwork.LoadBalancersClientListResponse] } - -type applicationInsightsAPI interface { - NewListByResourceGroupPager(resourceGroupName string, - options *armapplicationinsights.ComponentsClientListByResourceGroupOptions, - ) *runtime.Pager[armapplicationinsights.ComponentsClientListByResourceGroupResponse] -} diff --git a/internal/cloud/azure/logger.go b/internal/cloud/azure/logger.go deleted file mode 100644 index 160a77b1d..000000000 --- a/internal/cloud/azure/logger.go +++ /dev/null @@ -1,106 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package azure - -import ( - "context" - "errors" - "fmt" - "net/http" - - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights" - "github.com/edgelesssys/constellation/v2/internal/cloud" - "github.com/microsoft/ApplicationInsights-Go/appinsights" -) - -// Logger implements CloudLogger interface for Azure to Disclose early boot -// logs into Azure's App Insights service. -type Logger struct { - client appinsights.TelemetryClient -} - -// NewLogger creates a new client to store information in Azure Application Insights -// https://github.com/Microsoft/ApplicationInsights-go -func NewLogger(ctx context.Context) (*Logger, error) { - cred, err := azidentity.NewDefaultAzureCredential(nil) - if err != nil { - return nil, fmt.Errorf("loading credentials: %w", err) - } - imdsAPI := &IMDSClient{ - client: &http.Client{Transport: &http.Transport{Proxy: nil}}, - } - subscriptionID, err := imdsAPI.subscriptionID(ctx) - if err != nil { - return nil, fmt.Errorf("retrieving subscription ID: %w", err) - } - appInsightAPI, err := armapplicationinsights.NewComponentsClient(subscriptionID, cred, nil) - if err != nil { - return nil, fmt.Errorf("setting up insights API client. %w", err) - } - - instrumentationKey, err := getAppInsightsKey(ctx, imdsAPI, appInsightAPI) - if err != nil { - return nil, fmt.Errorf("getting app insights instrumentation key: %w", err) - } - - client := appinsights.NewTelemetryClient(instrumentationKey) - - name, err := imdsAPI.name(ctx) - if err != nil { - return nil, fmt.Errorf("retrieving instance name: %w", err) - } - client.Context().CommonProperties["instance-name"] = name - - return &Logger{client: client}, nil -} - -// Disclose stores log information in Azure Application Insights! -// Do **NOT** log sensitive information! -func (l *Logger) Disclose(msg string) { - l.client.Track(appinsights.NewTraceTelemetry(msg, appinsights.Information)) -} - -// Close blocks until all information are written to cloud API. -func (l *Logger) Close() error { - <-l.client.Channel().Close() - return nil -} - -// getAppInsightsKey returns a instrumentation key needed to set up cloud logging on Azure. -// The key is retrieved from the resource group of the instance the function is called from. -func getAppInsightsKey(ctx context.Context, imdsAPI imdsAPI, appInsightAPI applicationInsightsAPI) (string, error) { - resourceGroup, err := imdsAPI.resourceGroup(ctx) - if err != nil { - return "", err - } - uid, err := imdsAPI.uid(ctx) - if err != nil { - return "", err - } - - pager := appInsightAPI.NewListByResourceGroupPager(resourceGroup, nil) - for pager.More() { - page, err := pager.NextPage(ctx) - if err != nil { - return "", fmt.Errorf("retrieving application insights: %w", err) - } - - for _, component := range page.Value { - if component == nil || component.Tags == nil || - component.Tags[cloud.TagUID] == nil || *component.Tags[cloud.TagUID] != uid { - continue - } - - if component.Properties == nil || component.Properties.InstrumentationKey == nil { - return "", errors.New("unable to get instrumentation key") - } - return *component.Properties.InstrumentationKey, nil - } - } - return "", errors.New("could not find correctly tagged application insights") -} diff --git a/internal/cloud/azure/logger_test.go b/internal/cloud/azure/logger_test.go deleted file mode 100644 index a033c9c47..000000000 --- a/internal/cloud/azure/logger_test.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package azure - -import ( - "context" - "errors" - "testing" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/applicationinsights/armapplicationinsights" - "github.com/Azure/go-autorest/autorest/to" - "github.com/edgelesssys/constellation/v2/internal/cloud" - "github.com/stretchr/testify/assert" -) - -func TestGetAppInsightsKey(t *testing.T) { - someErr := errors.New("failed") - goodAppInsights := armapplicationinsights.Component{ - Tags: map[string]*string{ - cloud.TagUID: to.StringPtr("uid"), - }, - Properties: &armapplicationinsights.ComponentProperties{ - InstrumentationKey: to.StringPtr("key"), - }, - } - - testCases := map[string]struct { - imds *stubIMDSAPI - appInsights *stubApplicationsInsightsAPI - wantKey string - wantErr bool - }{ - "success": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{goodAppInsights}}, - }, - wantKey: "key", - }, - "multiple apps": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{ - { - Tags: map[string]*string{ - cloud.TagUID: to.StringPtr("different-uid"), - }, - Properties: &armapplicationinsights.ComponentProperties{ - InstrumentationKey: to.StringPtr("different-key"), - }, - }, - goodAppInsights, - }}, - }, - wantKey: "key", - }, - "missing properties": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{ - { - Tags: map[string]*string{ - cloud.TagUID: to.StringPtr("uid"), - }, - }, - }}, - }, - wantErr: true, - }, - "no app with matching uid": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{ - { - Tags: map[string]*string{ - cloud.TagUID: to.StringPtr("different-uid"), - }, - Properties: &armapplicationinsights.ComponentProperties{ - InstrumentationKey: to.StringPtr("different-key"), - }, - }, - }}, - }, - wantErr: true, - }, - "imds resource group error": { - imds: &stubIMDSAPI{ - resourceGroupErr: someErr, - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{goodAppInsights}}, - }, - wantErr: true, - }, - "imds uid error": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidErr: someErr, - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{list: []armapplicationinsights.Component{goodAppInsights}}, - }, - wantErr: true, - }, - "app insights list error": { - imds: &stubIMDSAPI{ - resourceGroupVal: "resource-group", - uidVal: "uid", - }, - appInsights: &stubApplicationsInsightsAPI{ - pager: &stubApplicationKeyPager{fetchErr: someErr}, - }, - wantErr: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - key, err := getAppInsightsKey(context.Background(), tc.imds, tc.appInsights) - if tc.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - assert.Equal(t, tc.wantKey, key) - } - }) - } -} - -type stubApplicationKeyPager struct { - list []armapplicationinsights.Component - fetchErr error - more bool -} - -func (p *stubApplicationKeyPager) moreFunc() func(armapplicationinsights.ComponentsClientListByResourceGroupResponse) bool { - return func(armapplicationinsights.ComponentsClientListByResourceGroupResponse) bool { - return p.more - } -} - -func (p *stubApplicationKeyPager) fetcherFunc() func(context.Context, *armapplicationinsights.ComponentsClientListByResourceGroupResponse, -) (armapplicationinsights.ComponentsClientListByResourceGroupResponse, error) { - return func(context.Context, *armapplicationinsights.ComponentsClientListByResourceGroupResponse) (armapplicationinsights.ComponentsClientListByResourceGroupResponse, error) { - page := make([]*armapplicationinsights.Component, len(p.list)) - for i := range p.list { - page[i] = &p.list[i] - } - return armapplicationinsights.ComponentsClientListByResourceGroupResponse{ - ComponentListResult: armapplicationinsights.ComponentListResult{ - Value: page, - }, - }, p.fetchErr - } -} - -type stubApplicationsInsightsAPI struct { - pager *stubApplicationKeyPager -} - -func (a *stubApplicationsInsightsAPI) NewListByResourceGroupPager(_ string, _ *armapplicationinsights.ComponentsClientListByResourceGroupOptions, -) *runtime.Pager[armapplicationinsights.ComponentsClientListByResourceGroupResponse] { - return runtime.NewPager(runtime.PagingHandler[armapplicationinsights.ComponentsClientListByResourceGroupResponse]{ - More: a.pager.moreFunc(), - Fetcher: a.pager.fetcherFunc(), - }) -} diff --git a/internal/cloud/gcp/BUILD.bazel b/internal/cloud/gcp/BUILD.bazel index fda87cca9..138f0c625 100644 --- a/internal/cloud/gcp/BUILD.bazel +++ b/internal/cloud/gcp/BUILD.bazel @@ -6,7 +6,6 @@ go_library( srcs = [ "gcp.go", "interface.go", - "logger.go", "wrappers.go", ], importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/gcp", @@ -20,7 +19,6 @@ go_library( "@com_google_cloud_go_compute//apiv1", "@com_google_cloud_go_compute//apiv1/computepb", "@com_google_cloud_go_compute_metadata//:metadata", - "@com_google_cloud_go_logging//:logging", "@org_golang_google_api//iterator", "@org_golang_google_protobuf//proto", ], diff --git a/internal/cloud/gcp/logger.go b/internal/cloud/gcp/logger.go deleted file mode 100644 index c366c63dd..000000000 --- a/internal/cloud/gcp/logger.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package gcp - -import ( - "context" - "fmt" - "log" - - "cloud.google.com/go/compute/metadata" - "cloud.google.com/go/logging" -) - -// Logger logs to GCP cloud logging. Do not use to log sensitive information. -type Logger struct { - client *logging.Client - logger *log.Logger -} - -// NewLogger creates a new Cloud Logger for GCP. -// https://cloud.google.com/logging/docs/setup/go -func NewLogger(ctx context.Context, logName string) (*Logger, error) { - projectID, err := metadata.NewClient(nil).ProjectID() - if err != nil { - return nil, fmt.Errorf("retrieving project ID from imds: %w", err) - } - - client, err := logging.NewClient(ctx, projectID) - if err != nil { - return nil, err - } - - logger := client.Logger(logName).StandardLogger(logging.Info) - - return &Logger{ - client: client, - logger: logger, - }, nil -} - -// Disclose stores log information in GCP Cloud Logging! Do **NOT** log sensitive -// information! -func (l *Logger) Disclose(msg string) { - l.logger.Println(msg) -} - -// Close waits for all buffer to be written. -func (l *Logger) Close() error { - return l.client.Close() -} diff --git a/internal/cloud/qemu/BUILD.bazel b/internal/cloud/qemu/BUILD.bazel index 5144883a4..ec4e2eadf 100644 --- a/internal/cloud/qemu/BUILD.bazel +++ b/internal/cloud/qemu/BUILD.bazel @@ -2,10 +2,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "qemu", - srcs = [ - "logger.go", - "qemu.go", - ], + srcs = ["qemu.go"], importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/qemu", visibility = ["//:__subpackages__"], deps = [ diff --git a/internal/cloud/qemu/logger.go b/internal/cloud/qemu/logger.go deleted file mode 100644 index 85846ed83..000000000 --- a/internal/cloud/qemu/logger.go +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (c) Edgeless Systems GmbH - -SPDX-License-Identifier: AGPL-3.0-only -*/ - -package qemu - -import ( - "context" - "net/http" - "net/url" - "strings" -) - -// Logger is a Cloud Logger for QEMU. -type Logger struct{} - -// NewLogger creates a new Cloud Logger for QEMU. -func NewLogger() *Logger { - return &Logger{} -} - -// Disclose writes log information to QEMU's cloud log. -// This is done by sending a POST request to the QEMU's metadata endpoint. -func (l *Logger) Disclose(msg string) { - url := &url.URL{ - Scheme: "http", - Host: qemuMetadataEndpoint, - Path: "/log", - } - - req, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, url.String(), strings.NewReader(msg)) - req.Header.Set("Content-Type", "application/json") - resp, err := http.DefaultClient.Do(req) - if err == nil { - defer resp.Body.Close() - } -} - -// Close is a no-op. -func (l *Logger) Close() error { - return nil -} diff --git a/terraform/infrastructure/aws/main.tf b/terraform/infrastructure/aws/main.tf index ac337a305..b65cad635 100644 --- a/terraform/infrastructure/aws/main.tf +++ b/terraform/infrastructure/aws/main.tf @@ -162,12 +162,6 @@ resource "aws_security_group" "security_group" { } -resource "aws_cloudwatch_log_group" "log_group" { - name = local.name - retention_in_days = 30 - tags = local.tags -} - module "load_balancer_targets" { for_each = { for port in local.load_balancer_ports : port.name => port } source = "./modules/load_balancer_target" diff --git a/terraform/infrastructure/azure/main.tf b/terraform/infrastructure/azure/main.tf index fd72ce836..4b3b7743a 100644 --- a/terraform/infrastructure/azure/main.tf +++ b/terraform/infrastructure/azure/main.tf @@ -77,14 +77,6 @@ resource "azurerm_attestation_provider" "attestation_provider" { } } -resource "azurerm_application_insights" "insights" { - name = local.name - location = var.location - resource_group_name = var.resource_group - application_type = "other" - tags = local.tags -} - resource "azurerm_public_ip" "loadbalancer_ip" { count = var.internal_load_balancer ? 0 : 1 name = "${local.name}-lb" diff --git a/terraform/infrastructure/gcp/main.tf b/terraform/infrastructure/gcp/main.tf index f11221349..36ce21be6 100644 --- a/terraform/infrastructure/gcp/main.tf +++ b/terraform/infrastructure/gcp/main.tf @@ -91,7 +91,6 @@ resource "google_compute_subnetwork" "vpc_subnetwork" { ] } - resource "google_compute_subnetwork" "proxy_subnet" { count = var.internal_load_balancer ? 1 : 0 name = "${local.name}-proxy" @@ -139,7 +138,6 @@ resource "google_compute_firewall" "firewall_external" { var.internal_load_balancer ? [22] : [], ]) } - } resource "google_compute_firewall" "firewall_internal_nodes" { @@ -166,7 +164,6 @@ resource "google_compute_firewall" "firewall_internal_pods" { allow { protocol = "icmp" } } - module "instance_group" { source = "./modules/instance_group" for_each = var.node_groups diff --git a/terraform/infrastructure/qemu/main.tf b/terraform/infrastructure/qemu/main.tf index 9bae7d582..047e9dbdc 100644 --- a/terraform/infrastructure/qemu/main.tf +++ b/terraform/infrastructure/qemu/main.tf @@ -30,6 +30,7 @@ resource "random_password" "init_secret" { special = true override_special = "_%@" } + resource "docker_image" "qemu_metadata" { name = var.metadata_api_image keep_locally = true