From 391763bc85be6d4bfdcd50c30903f5e24be9a4a8 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Fri, 24 May 2024 10:23:53 -0500 Subject: [PATCH] [NET-4414] Revert: Remove anyuid SCC requirement for OpenShift (#4034) Revert anyuid changes to see if it resolves issue --- .changelog/3813.txt | 3 - acceptance/framework/consul/helm_cluster.go | 63 ++--- .../api_gateway_kitchen_sink_test.go | 8 +- .../multiport-app/anyuid-scc-rolebinding.yaml | 26 ++ .../bases/multiport-app/kustomization.yaml | 3 +- .../static-client/anyuid-scc-rolebinding.yaml | 14 ++ .../bases/static-client/kustomization.yaml | 3 +- .../anyuid-scc-rolebinding.yaml | 14 ++ .../static-server-https/kustomization.yaml | 3 +- .../anyuid-scc-rolebinding.yaml | 14 ++ .../static-server-tcp/kustomization.yaml | 3 +- .../static-server/anyuid-scc-rolebinding.yaml | 14 ++ .../bases/static-server/kustomization.yaml | 3 +- .../anyuid-scc-rolebinding.yaml | 26 ++ .../bases/v2-multiport-app/kustomization.yaml | 3 +- .../connect-inject/common/openshift.go | 130 ---------- .../connect-inject/common/openshift_test.go | 236 ------------------ .../constants/annotations_and_labels.go | 6 - .../webhook/consul_dataplane_sidecar.go | 67 ++--- .../webhook/consul_dataplane_sidecar_test.go | 42 +--- .../connect-inject/webhook/container_init.go | 45 +--- .../webhook/container_init_test.go | 37 +-- .../webhook/redirect_traffic.go | 16 +- control-plane/go.mod | 2 +- control-plane/go.sum | 16 -- 25 files changed, 207 insertions(+), 590 deletions(-) delete mode 100644 .changelog/3813.txt create mode 100644 acceptance/tests/fixtures/bases/multiport-app/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-client/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-https/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/v2-multiport-app/anyuid-scc-rolebinding.yaml delete mode 100644 control-plane/connect-inject/common/openshift.go delete mode 100644 control-plane/connect-inject/common/openshift_test.go diff --git a/.changelog/3813.txt b/.changelog/3813.txt deleted file mode 100644 index 59ef045467..0000000000 --- a/.changelog/3813.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -control-plane: Remove anyuid Security Context Constraints (SCC) requirement in OpenShift. -``` diff --git a/acceptance/framework/consul/helm_cluster.go b/acceptance/framework/consul/helm_cluster.go index fafaceaca1..e037b53ef2 100644 --- a/acceptance/framework/consul/helm_cluster.go +++ b/acceptance/framework/consul/helm_cluster.go @@ -220,6 +220,7 @@ func (h *HelmCluster) Destroy(t *testing.T) { // Retry because sometimes certain resources (like PVC) take time to delete // in cloud providers. retry.RunWith(&retry.Counter{Wait: 2 * time.Second, Count: 600}, t, func(r *retry.R) { + // Force delete any pods that have h.releaseName in their name because sometimes // graceful termination takes a long time and since this is an uninstall // we don't care that they're stopped gracefully. @@ -240,9 +241,7 @@ func (h *HelmCluster) Destroy(t *testing.T) { require.NoError(r, err) for _, deployment := range deployments.Items { if strings.Contains(deployment.Name, h.releaseName) { - err := h.kubernetesClient.AppsV1(). - Deployments(h.helmOptions.KubectlOptions.Namespace). - Delete(context.Background(), deployment.Name, metav1.DeleteOptions{}) + err := h.kubernetesClient.AppsV1().Deployments(h.helmOptions.KubectlOptions.Namespace).Delete(context.Background(), deployment.Name, metav1.DeleteOptions{}) if !errors.IsNotFound(err) { require.NoError(r, err) } @@ -551,6 +550,7 @@ func (h *HelmCluster) SetupConsulClient(t *testing.T, secure bool, release ...st require.NoError(r, err) } }) + } } @@ -702,40 +702,47 @@ func configureNamespace(t *testing.T, client kubernetes.Interface, cfg *config.T } // configureSCCs creates RoleBindings that bind the default service account to cluster roles -// allowing access to the privileged Security Context Constraints on OpenShift. +// allowing access to the anyuid and privileged Security Context Constraints on OpenShift. func configureSCCs(t *testing.T, client kubernetes.Interface, cfg *config.TestConfig, namespace string) { + const anyuidClusterRole = "system:openshift:scc:anyuid" const privilegedClusterRole = "system:openshift:scc:privileged" + anyuidRoleBinding := "anyuid-test" privilegedRoleBinding := "privileged-test" // A role binding to allow default service account in the installation namespace access to the SCCs. - // Check if this cluster role binding already exists. - _, err := client.RbacV1().RoleBindings(namespace).Get(context.Background(), privilegedRoleBinding, metav1.GetOptions{}) - - if errors.IsNotFound(err) { - roleBinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: privilegedRoleBinding, - }, - Subjects: []rbacv1.Subject{ - { - Kind: rbacv1.ServiceAccountKind, - Name: "default", - Namespace: namespace, - }, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: privilegedClusterRole, - }, - } + { + for clusterRoleName, roleBindingName := range map[string]string{anyuidClusterRole: anyuidRoleBinding, privilegedClusterRole: privilegedRoleBinding} { + // Check if this cluster role binding already exists. + _, err := client.RbacV1().RoleBindings(namespace).Get(context.Background(), roleBindingName, metav1.GetOptions{}) + + if errors.IsNotFound(err) { + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleBindingName, + }, + Subjects: []rbacv1.Subject{ + { + Kind: rbacv1.ServiceAccountKind, + Name: "default", + Namespace: namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: clusterRoleName, + }, + } - _, err = client.RbacV1().RoleBindings(namespace).Create(context.Background(), roleBinding, metav1.CreateOptions{}) - require.NoError(t, err) - } else { - require.NoError(t, err) + _, err = client.RbacV1().RoleBindings(namespace).Create(context.Background(), roleBinding, metav1.CreateOptions{}) + require.NoError(t, err) + } else { + require.NoError(t, err) + } + } } helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + _ = client.RbacV1().RoleBindings(namespace).Delete(context.Background(), anyuidRoleBinding, metav1.DeleteOptions{}) _ = client.RbacV1().RoleBindings(namespace).Delete(context.Background(), privilegedRoleBinding, metav1.DeleteOptions{}) }) } diff --git a/acceptance/tests/api-gateway/api_gateway_kitchen_sink_test.go b/acceptance/tests/api-gateway/api_gateway_kitchen_sink_test.go index 9880298a2b..d701220a8c 100644 --- a/acceptance/tests/api-gateway/api_gateway_kitchen_sink_test.go +++ b/acceptance/tests/api-gateway/api_gateway_kitchen_sink_test.go @@ -142,10 +142,6 @@ func TestAPIGateway_KitchenSink(t *testing.T) { checkStatusCondition(r, gateway.Status.Conditions, trueCondition("ConsulAccepted", "Accepted")) require.Len(r, gateway.Status.Listeners, 2) - // http route checks - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute) - require.NoError(r, err) - require.EqualValues(r, int32(1), gateway.Status.Listeners[0].AttachedRoutes) checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("Accepted", "Accepted")) checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, falseCondition("Conflicted", "NoConflicts")) @@ -156,6 +152,10 @@ func TestAPIGateway_KitchenSink(t *testing.T) { // now we know we have an address, set it so we can use it gatewayAddress = gateway.Status.Addresses[0].Value + // http route checks + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute) + require.NoError(r, err) + // check our finalizers require.Len(r, httpRoute.Finalizers, 1) require.EqualValues(r, gatewayFinalizer, httpRoute.Finalizers[0]) diff --git a/acceptance/tests/fixtures/bases/multiport-app/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/multiport-app/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..5c2e0dcfa2 --- /dev/null +++ b/acceptance/tests/fixtures/bases/multiport-app/anyuid-scc-rolebinding.yaml @@ -0,0 +1,26 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: multiport-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: multiport +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: multiport-admin-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: multiport-admin diff --git a/acceptance/tests/fixtures/bases/multiport-app/kustomization.yaml b/acceptance/tests/fixtures/bases/multiport-app/kustomization.yaml index ecd2015a34..fb792d63a7 100644 --- a/acceptance/tests/fixtures/bases/multiport-app/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/multiport-app/kustomization.yaml @@ -7,4 +7,5 @@ resources: - secret.yaml - serviceaccount.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-client/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-client/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..b80bc5c562 --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-client/anyuid-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-client-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: static-client \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-client/kustomization.yaml b/acceptance/tests/fixtures/bases/static-client/kustomization.yaml index 929d64ac24..9aa0009dc4 100644 --- a/acceptance/tests/fixtures/bases/static-client/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/static-client/kustomization.yaml @@ -6,4 +6,5 @@ resources: - service.yaml - serviceaccount.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-https/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server-https/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..2be7cf13db --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-https/anyuid-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: static-server \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-https/kustomization.yaml b/acceptance/tests/fixtures/bases/static-server-https/kustomization.yaml index 6d7daa8f88..da166af201 100644 --- a/acceptance/tests/fixtures/bases/static-server-https/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/static-server-https/kustomization.yaml @@ -7,4 +7,5 @@ resources: - service.yaml - serviceaccount.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..eb86dc8bae --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-tcp-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: static-server-tcp \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml index 946e8d6b68..2180aa94e1 100644 --- a/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml @@ -7,4 +7,5 @@ resources: - serviceaccount.yaml - servicedefaults.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..2be7cf13db --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server/anyuid-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: static-server \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server/kustomization.yaml b/acceptance/tests/fixtures/bases/static-server/kustomization.yaml index 929d64ac24..9aa0009dc4 100644 --- a/acceptance/tests/fixtures/bases/static-server/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/static-server/kustomization.yaml @@ -6,4 +6,5 @@ resources: - service.yaml - serviceaccount.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/v2-multiport-app/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/v2-multiport-app/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..5c2e0dcfa2 --- /dev/null +++ b/acceptance/tests/fixtures/bases/v2-multiport-app/anyuid-scc-rolebinding.yaml @@ -0,0 +1,26 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: multiport-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: multiport +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: multiport-admin-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: multiport-admin diff --git a/acceptance/tests/fixtures/bases/v2-multiport-app/kustomization.yaml b/acceptance/tests/fixtures/bases/v2-multiport-app/kustomization.yaml index ecd2015a34..fb792d63a7 100644 --- a/acceptance/tests/fixtures/bases/v2-multiport-app/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/v2-multiport-app/kustomization.yaml @@ -7,4 +7,5 @@ resources: - secret.yaml - serviceaccount.yaml - psp-rolebinding.yaml - - privileged-scc-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/control-plane/connect-inject/common/openshift.go b/control-plane/connect-inject/common/openshift.go deleted file mode 100644 index e8e2f555e8..0000000000 --- a/control-plane/connect-inject/common/openshift.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Function copied from: -// https://github.com/openshift/apiserver-library-go/blob/release-4.17/pkg/securitycontextconstraints/sccmatching/matcher.go -// Apache 2.0 license: https://github.com/openshift/apiserver-library-go/blob/release-4.17/LICENSE - -// A namespace in OpenShift has the following annotations: -// Annotations: openshift.io/sa.scc.mcs: s0:c27,c4 -// openshift.io/sa.scc.uid-range: 1000710000/10000 -// openshift.io/sa.scc.supplemental-groups: 1000710000/10000 -// -// Note: Even though the annotation is named 'range', it is not a range but the ID you should use. All pods in a -// namespace should use the same UID/GID. (1000710000/1000710000 above) - -package common - -import ( - "fmt" - "strconv" - "strings" - - "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" - corev1 "k8s.io/api/core/v1" -) - -// GetOpenShiftUID gets the user id from the OpenShift annotation 'openshift.io/sa.scc.uid-range'. -func GetOpenShiftUID(ns *corev1.Namespace) (int64, error) { - annotation, ok := ns.Annotations[constants.AnnotationOpenShiftUIDRange] - if !ok { - return 0, fmt.Errorf("unable to find annotation %s", constants.AnnotationOpenShiftUIDRange) - } - if len(annotation) == 0 { - return 0, fmt.Errorf("found annotation %s but it was empty", constants.AnnotationOpenShiftUIDRange) - } - - uid, err := parseOpenShiftUID(annotation) - if err != nil { - return 0, err - } - - return uid, nil -} - -// parseOpenShiftUID parses the UID "range" from the annotation string. The annotation can either have a '/' or '-' -// as a separator. '-' is the old style of UID from when it used to be an actual range. -// Example annotation value: "1000700000/100000". -func parseOpenShiftUID(val string) (int64, error) { - var uid int64 - var err error - if strings.Contains(val, "/") { - str := strings.Split(val, "/") - uid, err = strconv.ParseInt(str[0], 10, 64) - if err != nil { - return 0, err - } - } - if strings.Contains(val, "-") { - str := strings.Split(val, "-") - uid, err = strconv.ParseInt(str[0], 10, 64) - if err != nil { - return 0, err - } - } - - if !strings.Contains(val, "/") && !strings.Contains(val, "-") { - return 0, fmt.Errorf( - "annotation %s contains an invalid format for value %s", - constants.AnnotationOpenShiftUIDRange, - val, - ) - } - - return uid, nil -} - -// GetOpenShiftGroup gets the group from OpenShift annotation 'openshift.io/sa.scc.supplemental-groups' -// Fall back to the UID annotation if the group annotation does not exist. The values should -// be the same. -func GetOpenShiftGroup(ns *corev1.Namespace) (int64, error) { - annotation, ok := ns.Annotations[constants.AnnotationOpenShiftGroups] - if !ok { - // fall back to UID annotation - annotation, ok = ns.Annotations[constants.AnnotationOpenShiftUIDRange] - if !ok { - return 0, fmt.Errorf( - "unable to find annotation %s or %s", - constants.AnnotationOpenShiftGroups, - constants.AnnotationOpenShiftUIDRange, - ) - } - } - if len(annotation) == 0 { - return 0, fmt.Errorf("found annotation %s but it was empty", constants.AnnotationOpenShiftGroups) - } - - uid, err := parseOpenShiftGroup(annotation) - if err != nil { - return 0, err - } - - return uid, nil -} - -// parseOpenShiftGroup parses the group from the annotation string. The annotation can either have a '/' or ',' -// as a separator. ',' is the old style of UID from when it used to be an actual range. -func parseOpenShiftGroup(val string) (int64, error) { - var group int64 - var err error - if strings.Contains(val, "/") { - str := strings.Split(val, "/") - group, err = strconv.ParseInt(str[0], 10, 64) - if err != nil { - return 0, err - } - } - if strings.Contains(val, ",") { - str := strings.Split(val, ",") - group, err = strconv.ParseInt(str[0], 10, 64) - if err != nil { - return 0, err - } - } - - if !strings.Contains(val, "/") && !strings.Contains(val, ",") { - return 0, fmt.Errorf("annotation %s contains an invalid format for value %s", constants.AnnotationOpenShiftGroups, val) - } - - return group, nil -} diff --git a/control-plane/connect-inject/common/openshift_test.go b/control-plane/connect-inject/common/openshift_test.go deleted file mode 100644 index e4a5178c7a..0000000000 --- a/control-plane/connect-inject/common/openshift_test.go +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 -package common - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestOpenShiftUID(t *testing.T) { - cases := []struct { - Name string - Namespace func() *corev1.Namespace - Expected int64 - Err string - }{ - { - Name: "Valid uid annotation with slash", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - constants.AnnotationOpenShiftUIDRange: "1000700000/100000", - }, - }, - } - return ns - }, - Expected: 1000700000, - Err: "", - }, - { - Name: "Valid uid annotation with dash", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - constants.AnnotationOpenShiftUIDRange: "1234-1000", - }, - }, - } - return ns - }, - Expected: 1234, - Err: "", - }, - { - Name: "Invalid uid annotation missing slash or dash", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - // annotation should have a slash '/' or dash '-' - constants.AnnotationOpenShiftUIDRange: "5678", - }, - }, - } - return ns - }, - Expected: 0, - Err: fmt.Sprintf( - "annotation %s contains an invalid format for value %s", - constants.AnnotationOpenShiftUIDRange, - "5678", - ), - }, - { - Name: "Missing uid annotation", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - }, - } - return ns - }, - Expected: 0, - Err: fmt.Sprintf("unable to find annotation %s", constants.AnnotationOpenShiftUIDRange), - }, - { - Name: "Empty", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - constants.AnnotationOpenShiftUIDRange: "", - }, - }, - } - return ns - }, - Expected: 0, - Err: "found annotation openshift.io/sa.scc.uid-range but it was empty", - }, - } - for _, tt := range cases { - t.Run(tt.Name, func(t *testing.T) { - require := require.New(t) - actual, err := GetOpenShiftUID(tt.Namespace()) - if tt.Err == "" { - require.NoError(err) - require.Equal(tt.Expected, actual) - } else { - require.EqualError(err, tt.Err) - } - }) - } -} - -func TestOpenShiftGroup(t *testing.T) { - cases := []struct { - Name string - Namespace func() *corev1.Namespace - Expected int64 - Err string - }{ - { - Name: "Valid group annotation with slash", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - constants.AnnotationOpenShiftGroups: "123456789/1000", - }, - }, - } - return ns - }, - Expected: 123456789, - Err: "", - }, - { - Name: "Valid group annotation with comma", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - constants.AnnotationOpenShiftGroups: "1234,1000", - }, - }, - } - return ns - }, - Expected: 1234, - Err: "", - }, - { - Name: "Invalid group annotation missing slash or comma", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - // annotation should have a slash '/' or comma ',' - constants.AnnotationOpenShiftGroups: "5678", - }, - }, - } - return ns - }, - Expected: 0, - Err: fmt.Sprintf( - "annotation %s contains an invalid format for value %s", - constants.AnnotationOpenShiftGroups, - "5678", - ), - }, - { - Name: "Missing group annotation, fall back to UID annotation", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - Annotations: map[string]string{ - // annotation should have a slash '/' or comma ',' - constants.AnnotationOpenShiftUIDRange: "9012/1000", - }, - }, - } - return ns - }, - Expected: 9012, - Err: "", - }, - { - Name: "Missing both group and fallback uid annotation", - Namespace: func() *corev1.Namespace { - ns := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - }, - } - return ns - }, - Expected: 0, - Err: fmt.Sprintf( - "unable to find annotation %s or %s", - constants.AnnotationOpenShiftGroups, - constants.AnnotationOpenShiftUIDRange, - ), - }, - } - for _, tt := range cases { - t.Run(tt.Name, func(t *testing.T) { - require := require.New(t) - actual, err := GetOpenShiftGroup(tt.Namespace()) - if tt.Err == "" { - require.NoError(err) - require.Equal(tt.Expected, actual) - } else { - require.EqualError(err, tt.Err) - } - }) - } -} diff --git a/control-plane/connect-inject/constants/annotations_and_labels.go b/control-plane/connect-inject/constants/annotations_and_labels.go index dca3c523a3..e31fd22bf3 100644 --- a/control-plane/connect-inject/constants/annotations_and_labels.go +++ b/control-plane/connect-inject/constants/annotations_and_labels.go @@ -274,9 +274,3 @@ const ( AnnotationPrometheusPath = "prometheus.io/path" AnnotationPrometheusPort = "prometheus.io/port" ) - -// Annotations used by OpenShift. -const ( - AnnotationOpenShiftGroups = "openshift.io/sa.scc.supplemental-groups" - AnnotationOpenShiftUIDRange = "openshift.io/sa.scc.uid-range" -) diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go index dc9ca0d0bf..13bf3f7bd1 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -214,58 +214,29 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor // When transparent proxy is enabled, then consul-dataplane needs to run as our specific user // so that traffic redirection will work. if tproxyEnabled || !w.EnableOpenShift { - // In non-OpenShift environments we set the User and group ID for the sidecar to our values. - if !w.EnableOpenShift { - if pod.Spec.SecurityContext != nil { - // User container and consul-dataplane container cannot have the same UID. - if pod.Spec.SecurityContext.RunAsUser != nil && *pod.Spec.SecurityContext.RunAsUser == sidecarUserAndGroupID { - return corev1.Container{}, fmt.Errorf( - "pod's security context cannot have the same UID as consul-dataplane: %v", - sidecarUserAndGroupID, - ) - } + if pod.Spec.SecurityContext != nil { + // User container and consul-dataplane container cannot have the same UID. + if pod.Spec.SecurityContext.RunAsUser != nil && *pod.Spec.SecurityContext.RunAsUser == sidecarUserAndGroupID { + return corev1.Container{}, fmt.Errorf("pod's security context cannot have the same UID as consul-dataplane: %v", sidecarUserAndGroupID) } - // Ensure that none of the user's containers have the same UID as consul-dataplane. At this point in injection the meshWebhook - // has only injected init containers so all containers defined in pod.Spec.Containers are from the user. - for _, c := range pod.Spec.Containers { - // User container and consul-dataplane container cannot have the same UID. - if c.SecurityContext != nil && c.SecurityContext.RunAsUser != nil && - *c.SecurityContext.RunAsUser == sidecarUserAndGroupID && - c.Image != w.ImageConsulDataplane { - return corev1.Container{}, fmt.Errorf( - "container %q has runAsUser set to the same UID \"%d\" as consul-dataplane which is not allowed", - c.Name, - sidecarUserAndGroupID, - ) - } - } - container.SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(sidecarUserAndGroupID), - RunAsGroup: pointer.Int64(sidecarUserAndGroupID), - RunAsNonRoot: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), - ReadOnlyRootFilesystem: pointer.Bool(true), - } - } else { - // Transparent proxy is set in OpenShift. There is an annotation on the namespace that tells us what - // the user and group ids should be for the sidecar. - uid, err := common.GetOpenShiftUID(&namespace) - if err != nil { - return corev1.Container{}, err - } - group, err := common.GetOpenShiftGroup(&namespace) - if err != nil { - return corev1.Container{}, err - } - container.SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(uid), - RunAsGroup: pointer.Int64(group), - RunAsNonRoot: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), - ReadOnlyRootFilesystem: pointer.Bool(true), + } + // Ensure that none of the user's containers have the same UID as consul-dataplane. At this point in injection the meshWebhook + // has only injected init containers so all containers defined in pod.Spec.Containers are from the user. + for _, c := range pod.Spec.Containers { + // User container and consul-dataplane container cannot have the same UID. + if c.SecurityContext != nil && c.SecurityContext.RunAsUser != nil && *c.SecurityContext.RunAsUser == sidecarUserAndGroupID && c.Image != w.ImageConsulDataplane { + return corev1.Container{}, fmt.Errorf("container %q has runAsUser set to the same UID \"%d\" as consul-dataplane which is not allowed", c.Name, sidecarUserAndGroupID) } } + container.SecurityContext = &corev1.SecurityContext{ + RunAsUser: pointer.Int64(sidecarUserAndGroupID), + RunAsGroup: pointer.Int64(sidecarUserAndGroupID), + RunAsNonRoot: pointer.Bool(true), + AllowPrivilegeEscalation: pointer.Bool(false), + ReadOnlyRootFilesystem: pointer.Bool(true), + } } + return container, nil } diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go index 4a8386c493..ae1f50e795 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go @@ -304,6 +304,7 @@ func TestHandlerConsulDataplaneSidecar_Concurrency(t *testing.T) { // Test that we pass the dns proxy flag to dataplane correctly. func TestHandlerConsulDataplaneSidecar_DNSProxy(t *testing.T) { + // We only want the flag passed when DNS and tproxy are both enabled. DNS/tproxy can // both be enabled/disabled with annotations/labels on the pod and namespace and then globally // through the helm chart. To test this we use an outer loop with the possible DNS settings and then @@ -364,6 +365,7 @@ func TestHandlerConsulDataplaneSidecar_DNSProxy(t *testing.T) { for i, dnsCase := range dnsCases { for j, tproxyCase := range tproxyCases { t.Run(fmt.Sprintf("dns=%d,tproxy=%d", i, j), func(t *testing.T) { + // Test setup. h := MeshWebhook{ ConsulConfig: &consul.Config{HTTPPort: 8500, GRPCPort: 8502}, @@ -828,8 +830,8 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) { tproxyEnabled: true, openShiftEnabled: true, expSecurityContext: &corev1.SecurityContext{ - RunAsUser: pointer.Int64(1000700000), - RunAsGroup: pointer.Int64(1000700000), + RunAsUser: pointer.Int64(sidecarUserAndGroupID), + RunAsGroup: pointer.Int64(sidecarUserAndGroupID), RunAsNonRoot: pointer.Bool(true), ReadOnlyRootFilesystem: pointer.Bool(true), AllowPrivilegeEscalation: pointer.Bool(false), @@ -837,19 +839,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) { }, } for name, c := range cases { - ns := corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: k8sNamespace, - Namespace: k8sNamespace, - Annotations: map[string]string{}, - Labels: map[string]string{}, - }, - } - - if c.openShiftEnabled { - ns.Annotations[constants.AnnotationOpenShiftUIDRange] = "1000700000/100000" - ns.Annotations[constants.AnnotationOpenShiftGroups] = "1000700000/100000" - } t.Run(name, func(t *testing.T) { w := MeshWebhook{ EnableTransparentProxy: c.tproxyEnabled, @@ -858,7 +847,6 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) { } pod := corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Namespace: ns.Name, Annotations: map[string]string{ constants.AnnotationService: "foo", }, @@ -872,7 +860,7 @@ func TestHandlerConsulDataplaneSidecar_withSecurityContext(t *testing.T) { }, }, } - ec, err := w.consulDataplaneSidecar(ns, pod, multiPortInfo{}) + ec, err := w.consulDataplaneSidecar(testNS, pod, multiPortInfo{}) require.NoError(t, err) require.Equal(t, c.expSecurityContext, ec.SecurityContext) }) @@ -899,10 +887,7 @@ func TestHandlerConsulDataplaneSidecar_FailsWithDuplicatePodSecurityContextUID(t }, } _, err := w.consulDataplaneSidecar(testNS, pod, multiPortInfo{}) - require.EqualError( - err, - fmt.Sprintf("pod's security context cannot have the same UID as consul-dataplane: %v", sidecarUserAndGroupID), - ) + require.EqualError(err, fmt.Sprintf("pod's security context cannot have the same UID as consul-dataplane: %v", sidecarUserAndGroupID)) } // Test that if the user specifies a container with security context with the same uid as `sidecarUserAndGroupID` that we @@ -939,12 +924,9 @@ func TestHandlerConsulDataplaneSidecar_FailsWithDuplicateContainerSecurityContex }, }, }, - webhook: MeshWebhook{}, - expErr: true, - expErrMessage: fmt.Sprintf( - "container \"app\" has runAsUser set to the same UID \"%d\" as consul-dataplane which is not allowed", - sidecarUserAndGroupID, - ), + webhook: MeshWebhook{}, + expErr: true, + expErrMessage: fmt.Sprintf("container \"app\" has runAsUser set to the same UID \"%d\" as consul-dataplane which is not allowed", sidecarUserAndGroupID), }, { name: "doesn't fail with envoy image", @@ -1407,11 +1389,7 @@ func TestHandlerConsulDataplaneSidecar_Metrics(t *testing.T) { }, }, expCmdArgs: "", - expErr: fmt.Sprintf( - "must set one of %q or %q when providing prometheus TLS config", - constants.AnnotationPrometheusCAFile, - constants.AnnotationPrometheusCAPath, - ), + expErr: fmt.Sprintf("must set one of %q or %q when providing prometheus TLS config", constants.AnnotationPrometheusCAFile, constants.AnnotationPrometheusCAPath), }, { name: "merge metrics with TLS enabled, missing cert gives an error", diff --git a/control-plane/connect-inject/webhook/container_init.go b/control-plane/connect-inject/webhook/container_init.go index 24c71461af..2626b03689 100644 --- a/control-plane/connect-inject/webhook/container_init.go +++ b/control-plane/connect-inject/webhook/container_init.go @@ -255,41 +255,16 @@ func (w *MeshWebhook) containerInit(namespace corev1.Namespace, pod corev1.Pod, }, } } else { - if !w.EnableOpenShift { - container.SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(initContainersUserAndGroupID), - RunAsGroup: pointer.Int64(initContainersUserAndGroupID), - RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(privileged), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{"ALL"}, - }, - ReadOnlyRootFilesystem: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), - } - } else { - // Transparent proxy + CNI is set in OpenShift. There is an annotation on the namespace that tells us what - // the user and group ids should be for the sidecar. - uid, err := common.GetOpenShiftUID(&namespace) - if err != nil { - return corev1.Container{}, err - } - group, err := common.GetOpenShiftGroup(&namespace) - if err != nil { - return corev1.Container{}, err - } - container.SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(uid), - RunAsGroup: pointer.Int64(group), - RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{"ALL"}, - }, - ReadOnlyRootFilesystem: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), - } - + container.SecurityContext = &corev1.SecurityContext{ + RunAsUser: pointer.Int64(initContainersUserAndGroupID), + RunAsGroup: pointer.Int64(initContainersUserAndGroupID), + RunAsNonRoot: pointer.Bool(true), + Privileged: pointer.Bool(privileged), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + ReadOnlyRootFilesystem: pointer.Bool(true), + AllowPrivilegeEscalation: pointer.Bool(false), } } } diff --git a/control-plane/connect-inject/webhook/container_init_test.go b/control-plane/connect-inject/webhook/container_init_test.go index 5896c0c0eb..8feac95b84 100644 --- a/control-plane/connect-inject/webhook/container_init_test.go +++ b/control-plane/connect-inject/webhook/container_init_test.go @@ -293,7 +293,7 @@ func TestHandlerContainerInit_transparentProxy(t *testing.T) { } var expectedSecurityContext *corev1.SecurityContext - if c.cniEnabled && !c.openShiftEnabled { + if c.cniEnabled { expectedSecurityContext = &corev1.SecurityContext{ RunAsUser: pointer.Int64(initContainersUserAndGroupID), RunAsGroup: pointer.Int64(initContainersUserAndGroupID), @@ -315,34 +315,8 @@ func TestHandlerContainerInit_transparentProxy(t *testing.T) { Add: []corev1.Capability{netAdminCapability}, }, } - } else if c.cniEnabled && c.openShiftEnabled { - // When cni + openShift - expectedSecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(1000700000), - RunAsGroup: pointer.Int64(1000700000), - RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(privileged), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{"ALL"}, - }, - ReadOnlyRootFilesystem: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), - } } - ns := corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: k8sNamespace, - Namespace: k8sNamespace, - Annotations: map[string]string{}, - Labels: map[string]string{}, - }, - } - - if c.openShiftEnabled { - ns.Annotations[constants.AnnotationOpenShiftUIDRange] = "1000700000/100000" - ns.Annotations[constants.AnnotationOpenShiftGroups] = "1000700000/100000" - } - + ns := testNS ns.Labels = c.namespaceLabel container, err := w.containerInit(ns, *pod, multiPortInfo{}) require.NoError(t, err) @@ -811,8 +785,7 @@ func TestHandlerContainerInit_Multiport(t *testing.T) { serviceName: "web-admin", }, }, - []string{ - `/bin/sh -ec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${POD_NAMESPACE} \ + []string{`/bin/sh -ec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${POD_NAMESPACE} \ -log-level=info \ -log-json=false \ -multiport=true \ @@ -850,8 +823,7 @@ func TestHandlerContainerInit_Multiport(t *testing.T) { serviceName: "web-admin", }, }, - []string{ - `/bin/sh -ec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${POD_NAMESPACE} \ + []string{`/bin/sh -ec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${POD_NAMESPACE} \ -log-level=info \ -log-json=false \ -service-account-name="web" \ @@ -950,6 +922,7 @@ func TestHandlerContainerInit_WithTLSAndCustomPorts(t *testing.T) { } } } + }) } } diff --git a/control-plane/connect-inject/webhook/redirect_traffic.go b/control-plane/connect-inject/webhook/redirect_traffic.go index e6de09f448..f928df4afd 100644 --- a/control-plane/connect-inject/webhook/redirect_traffic.go +++ b/control-plane/connect-inject/webhook/redirect_traffic.go @@ -19,7 +19,7 @@ import ( // iptables.Config: // // ConsulDNSIP: an environment variable named RESOURCE_PREFIX_DNS_SERVICE_HOST where RESOURCE_PREFIX is the consul.fullname in helm. -// ProxyUserID: a constant set in Annotations or read from namespace when using OpenShift +// ProxyUserID: a constant set in Annotations // ProxyInboundPort: the service port or bind port // ProxyOutboundPort: default transparent proxy outbound port or transparent proxy outbound listener port // ExcludeInboundPorts: prometheus, envoy stats, expose paths, checks and excluded pod annotations @@ -27,18 +27,8 @@ import ( // ExcludeOutboundCIDRs: pod annotations // ExcludeUIDs: pod annotations func (w *MeshWebhook) iptablesConfigJSON(pod corev1.Pod, ns corev1.Namespace) (string, error) { - cfg := iptables.Config{} - - if !w.EnableOpenShift { - cfg.ProxyUserID = strconv.Itoa(sidecarUserAndGroupID) - } else { - // When using OpenShift, the uid and group are saved as an annotation on the namespace - uid, err := common.GetOpenShiftUID(&ns) - if err != nil { - return "", err - } - cfg.ProxyUserID = strconv.FormatInt(uid, 10) - + cfg := iptables.Config{ + ProxyUserID: strconv.Itoa(sidecarUserAndGroupID), } // Set the proxy's inbound port. diff --git a/control-plane/go.mod b/control-plane/go.mod index 3cb3f162eb..0dcb16ddf8 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -162,4 +162,4 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) -go 1.21 +go 1.20 diff --git a/control-plane/go.sum b/control-plane/go.sum index 1246c87421..a406f25b8c 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -35,7 +35,6 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= -github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -52,7 +51,6 @@ github.com/aws/aws-sdk-go v1.44.262 h1:gyXpcJptWoNkK+DiAiaBltlreoWKQXjAIh6FRh60F github.com/aws/aws-sdk-go v1.44.262/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -98,7 +96,6 @@ github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nb github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -144,9 +141,7 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= -github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= 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= @@ -173,7 +168,6 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -192,7 +186,6 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -236,7 +229,6 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -284,7 +276,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk= -github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 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= @@ -306,7 +297,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -369,12 +359,10 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -414,7 +402,6 @@ github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOe github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -462,7 +449,6 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -639,9 +625,7 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=