From 68e99ebb95c944eef6f53fd11bf5d811c2d6fb07 Mon Sep 17 00:00:00 2001 From: Niranjan Shankar Date: Fri, 2 Sep 2022 15:00:34 -0400 Subject: [PATCH] Remove crd conversion webhook (#5065) Signed-off-by: nshankar13 --- .../templates/osm-bootstrap-deployment.yaml | 12 -- .../crds/config_mesh_root_certificate.yaml | 2 + cmd/osm-bootstrap/crds/config_meshconfig.yaml | 2 + cmd/osm-bootstrap/crds/policy_egress.yaml | 2 + .../crds/policy_ingress_backend.yaml | 2 + cmd/osm-bootstrap/crds/policy_retry.yaml | 2 + .../crds/policy_upstream_traffic_setting.yaml | 2 + .../crds/smi_http_route_group.yaml | 2 + cmd/osm-bootstrap/crds/smi_tcp_route.yaml | 2 + .../crds/smi_traffic_access.yaml | 2 + cmd/osm-bootstrap/crds/smi_traffic_split.yaml | 2 + cmd/osm-bootstrap/osm-bootstrap.go | 138 +++++++------ dockerfiles/Dockerfile.osm-bootstrap | 1 + go.mod | 1 - go.sum | 1 - pkg/constants/constants.go | 3 - .../config_meshconfig_conversion.go | 67 ------ .../config_meshconfig_conversion_test.go | 85 -------- pkg/crdconversion/crdconversion.go | 97 --------- pkg/crdconversion/crdconversion_test.go | 106 ---------- pkg/crdconversion/framework.go | 193 ------------------ pkg/crdconversion/framework_test.go | 139 ------------- pkg/crdconversion/policy_egress_conversion.go | 27 --- .../policy_ingressbackends_conversion.go | 27 --- pkg/crdconversion/policy_retry_conversion.go | 27 --- .../smi_httproutegroup_conversion.go | 27 --- pkg/crdconversion/smi_tcproutes_conversion.go | 27 --- .../smi_trafficaccess_conversion.go | 27 --- .../smi_trafficsplit_conversion.go | 27 --- pkg/crdconversion/types.go | 9 - pkg/metricsstore/metricsstore.go | 10 - 31 files changed, 92 insertions(+), 979 deletions(-) delete mode 100644 pkg/crdconversion/config_meshconfig_conversion.go delete mode 100644 pkg/crdconversion/config_meshconfig_conversion_test.go delete mode 100644 pkg/crdconversion/crdconversion.go delete mode 100644 pkg/crdconversion/crdconversion_test.go delete mode 100644 pkg/crdconversion/framework.go delete mode 100644 pkg/crdconversion/framework_test.go delete mode 100644 pkg/crdconversion/policy_egress_conversion.go delete mode 100644 pkg/crdconversion/policy_ingressbackends_conversion.go delete mode 100644 pkg/crdconversion/policy_retry_conversion.go delete mode 100644 pkg/crdconversion/smi_httproutegroup_conversion.go delete mode 100644 pkg/crdconversion/smi_tcproutes_conversion.go delete mode 100644 pkg/crdconversion/smi_trafficaccess_conversion.go delete mode 100644 pkg/crdconversion/smi_trafficsplit_conversion.go delete mode 100644 pkg/crdconversion/types.go diff --git a/charts/osm/templates/osm-bootstrap-deployment.yaml b/charts/osm/templates/osm-bootstrap-deployment.yaml index cc67608aa6..7135335c14 100644 --- a/charts/osm/templates/osm-bootstrap-deployment.yaml +++ b/charts/osm/templates/osm-bootstrap-deployment.yaml @@ -33,18 +33,6 @@ spec: {{- if not (.Capabilities.APIVersions.Has "security.openshift.io/v1") }} {{- include "restricted.securityContext" . | nindent 6 }} {{- end }} - initContainers: - - name: init-osm-bootstrap - image: "{{ include "osmCRDs.image" . }}" - imagePullPolicy: {{ .Values.osm.image.pullPolicy }} - command: - - sh - - -c - - > - kubectl apply -f /osm-crds; - {{- if .Values.osm.enableReconciler }} - kubectl label -f /osm-crds openservicemesh.io/reconcile=true --overwrite; - {{- end }} containers: - name: osm-bootstrap image: "{{ include "osmBootstrap.image" . }}" diff --git a/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml b/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml index d67a8bddec..c07890d867 100644 --- a/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml +++ b/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml @@ -30,6 +30,8 @@ spec: - mrc singular: meshrootcertificate plural: meshrootcertificates + conversion: + strategy: None versions: - name: v1alpha2 served: true diff --git a/cmd/osm-bootstrap/crds/config_meshconfig.yaml b/cmd/osm-bootstrap/crds/config_meshconfig.yaml index 40bf9c87d4..1c9844ca3a 100644 --- a/cmd/osm-bootstrap/crds/config_meshconfig.yaml +++ b/cmd/osm-bootstrap/crds/config_meshconfig.yaml @@ -30,6 +30,8 @@ spec: - meshconfig singular: meshconfig plural: meshconfigs + conversion: + strategy: None versions: - name: v1alpha2 served: true diff --git a/cmd/osm-bootstrap/crds/policy_egress.yaml b/cmd/osm-bootstrap/crds/policy_egress.yaml index 0672a578f6..d504fcc077 100644 --- a/cmd/osm-bootstrap/crds/policy_egress.yaml +++ b/cmd/osm-bootstrap/crds/policy_egress.yaml @@ -30,6 +30,8 @@ spec: - egress singular: egress plural: egresses + conversion: + strategy: None versions: - name: v1alpha1 served: true diff --git a/cmd/osm-bootstrap/crds/policy_ingress_backend.yaml b/cmd/osm-bootstrap/crds/policy_ingress_backend.yaml index 541412d84a..a4fc65f292 100644 --- a/cmd/osm-bootstrap/crds/policy_ingress_backend.yaml +++ b/cmd/osm-bootstrap/crds/policy_ingress_backend.yaml @@ -30,6 +30,8 @@ spec: - ingressbackend singular: ingressbackend plural: ingressbackends + conversion: + strategy: None versions: - name: v1alpha1 served: true diff --git a/cmd/osm-bootstrap/crds/policy_retry.yaml b/cmd/osm-bootstrap/crds/policy_retry.yaml index c87aea970e..622da35e9f 100644 --- a/cmd/osm-bootstrap/crds/policy_retry.yaml +++ b/cmd/osm-bootstrap/crds/policy_retry.yaml @@ -30,6 +30,8 @@ spec: - retry singular: retry plural: retries + conversion: + strategy: None versions: - name: v1alpha1 served: true diff --git a/cmd/osm-bootstrap/crds/policy_upstream_traffic_setting.yaml b/cmd/osm-bootstrap/crds/policy_upstream_traffic_setting.yaml index 8014b06343..fdd77d3503 100644 --- a/cmd/osm-bootstrap/crds/policy_upstream_traffic_setting.yaml +++ b/cmd/osm-bootstrap/crds/policy_upstream_traffic_setting.yaml @@ -30,6 +30,8 @@ spec: - upstreamtrafficsetting singular: upstreamtrafficsetting plural: upstreamtrafficsettings + conversion: + strategy: None versions: - name: v1alpha1 served: true diff --git a/cmd/osm-bootstrap/crds/smi_http_route_group.yaml b/cmd/osm-bootstrap/crds/smi_http_route_group.yaml index c49df40ab6..f64420869b 100644 --- a/cmd/osm-bootstrap/crds/smi_http_route_group.yaml +++ b/cmd/osm-bootstrap/crds/smi_http_route_group.yaml @@ -29,6 +29,8 @@ spec: - htr plural: httproutegroups singular: httproutegroup + conversion: + strategy: None versions: - name: v1alpha4 served: true diff --git a/cmd/osm-bootstrap/crds/smi_tcp_route.yaml b/cmd/osm-bootstrap/crds/smi_tcp_route.yaml index 9891728df8..9efeeca56b 100644 --- a/cmd/osm-bootstrap/crds/smi_tcp_route.yaml +++ b/cmd/osm-bootstrap/crds/smi_tcp_route.yaml @@ -29,6 +29,8 @@ spec: - tr plural: tcproutes singular: tcproute + conversion: + strategy: None versions: - name: v1alpha4 served: true diff --git a/cmd/osm-bootstrap/crds/smi_traffic_access.yaml b/cmd/osm-bootstrap/crds/smi_traffic_access.yaml index b4b2b24908..f2cc5b2f81 100644 --- a/cmd/osm-bootstrap/crds/smi_traffic_access.yaml +++ b/cmd/osm-bootstrap/crds/smi_traffic_access.yaml @@ -29,6 +29,8 @@ spec: - tt plural: traffictargets singular: traffictarget + conversion: + strategy: None versions: - name: v1alpha3 served: true diff --git a/cmd/osm-bootstrap/crds/smi_traffic_split.yaml b/cmd/osm-bootstrap/crds/smi_traffic_split.yaml index cb9cb2c5e0..214fa2da9a 100644 --- a/cmd/osm-bootstrap/crds/smi_traffic_split.yaml +++ b/cmd/osm-bootstrap/crds/smi_traffic_split.yaml @@ -30,6 +30,8 @@ spec: - ts plural: trafficsplits singular: trafficsplit + conversion: + strategy: None versions: - name: v1alpha4 served: false diff --git a/cmd/osm-bootstrap/osm-bootstrap.go b/cmd/osm-bootstrap/osm-bootstrap.go index 391a289558..5a9c1960ad 100644 --- a/cmd/osm-bootstrap/osm-bootstrap.go +++ b/cmd/osm-bootstrap/osm-bootstrap.go @@ -11,36 +11,34 @@ import ( "fmt" "net/http" "os" - "time" + "path/filepath" + "strconv" "github.com/spf13/pflag" admissionv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" + apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/kubernetes" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/clientcmd" "k8s.io/kubectl/pkg/util" configv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2" - "github.com/openservicemesh/osm/pkg/certificate" configClientset "github.com/openservicemesh/osm/pkg/gen/client/config/clientset/versioned" "github.com/openservicemesh/osm/pkg/health" - "github.com/openservicemesh/osm/pkg/k8s" "github.com/openservicemesh/osm/pkg/certificate/providers" "github.com/openservicemesh/osm/pkg/constants" - "github.com/openservicemesh/osm/pkg/crdconversion" "github.com/openservicemesh/osm/pkg/httpserver" "github.com/openservicemesh/osm/pkg/k8s/events" - "github.com/openservicemesh/osm/pkg/k8s/informers" "github.com/openservicemesh/osm/pkg/logger" - "github.com/openservicemesh/osm/pkg/messaging" "github.com/openservicemesh/osm/pkg/metricsstore" "github.com/openservicemesh/osm/pkg/reconciler" "github.com/openservicemesh/osm/pkg/signals" @@ -68,7 +66,6 @@ var ( certProviderKind string enableMeshRootCertificate bool - tresorOptions providers.TresorOptions vaultOptions providers.VaultOptions certManagerOptions providers.CertManagerOptions @@ -124,21 +121,6 @@ func init() { _ = admissionv1.AddToScheme(scheme) } -// TODO(#4502): This function can be deleted once we get rid of cert options. -func getCertOptions() (providers.Options, error) { - switch providers.Kind(certProviderKind) { - case providers.TresorKind: - tresorOptions.SecretName = caBundleSecretName - return tresorOptions, nil - case providers.VaultKind: - vaultOptions.VaultTokenSecretNamespace = osmNamespace - return vaultOptions, nil - case providers.CertManagerKind: - return certManagerOptions, nil - } - return nil, fmt.Errorf("unknown certificate provider kind: %s", certProviderKind) -} - func main() { log.Info().Msgf("Starting osm-bootstrap %s; %s; %s", version.Version, version.GitCommit, version.BuildDate) if err := parseFlags(); err != nil { @@ -175,6 +157,8 @@ func main() { namespace: osmNamespace, } + applyOrUpdateCRDs(crdClient) + err = bootstrap.ensureMeshConfig() if err != nil { log.Fatal().Err(err).Msgf("Error setting up default MeshConfig %s from ConfigMap %s", meshConfigName, presetMeshConfigName) @@ -194,7 +178,7 @@ func main() { log.Fatal().Err(err).Msg("Error initializing Kubernetes events recorder") } - ctx, cancel := context.WithCancel(context.Background()) + _, cancel := context.WithCancel(context.Background()) defer cancel() stop := signals.RegisterExitHandlers(cancel) @@ -203,49 +187,22 @@ func main() { metricsstore.DefaultMetricsStore.ErrCodeCounter, metricsstore.DefaultMetricsStore.HTTPResponseTotal, metricsstore.DefaultMetricsStore.HTTPResponseDuration, - metricsstore.DefaultMetricsStore.ConversionWebhookResourceTotal, metricsstore.DefaultMetricsStore.ReconciliationTotal, ) - msgBroker := messaging.NewBroker(stop) - - informerCollection, err := informers.NewInformerCollection(meshName, stop, - informers.WithKubeClient(kubeClient), - informers.WithConfigClient(configClient, osmMeshConfigName, osmNamespace), - ) - - if err != nil { - events.GenericEventRecorder().FatalEvent(err, events.InitializationError, "Error creating informer collection") - } - - certOpts, err := getCertOptions() - if err != nil { - log.Fatal().Err(err).Msg("Error getting certificate options") - } - - k8sClient := k8s.NewClient(osmNamespace, osmMeshConfigName, informerCollection, nil, msgBroker) - - var certManager *certificate.Manager - if enableMeshRootCertificate { - certManager, err = providers.NewCertificateManagerFromMRC(ctx, kubeClient, kubeConfig, osmNamespace, certOpts, k8sClient, informerCollection, 5*time.Second) - if err != nil { - events.GenericEventRecorder().FatalEvent(err, events.InvalidCertificateManager, - "Error initializing certificate manager of kind %s from MRC", certProviderKind) - } - } else { - certManager, err = providers.NewCertificateManager(ctx, kubeClient, kubeConfig, osmNamespace, certOpts, k8sClient, 5*time.Second, trustDomain) + version.SetMetric() + /* + * Initialize osm-bootstrap's HTTP server + */ + if enableReconciler { + log.Info().Msgf("OSM reconciler enabled for custom resource definitions") + err = reconciler.NewReconcilerClient(kubeClient, apiServerClient, meshName, osmVersion, stop, reconciler.CrdInformerKey) if err != nil { - events.GenericEventRecorder().FatalEvent(err, events.InvalidCertificateManager, - "Error initializing certificate manager of kind %s", certProviderKind) + events.GenericEventRecorder().FatalEvent(err, events.InitializationError, "Error creating reconciler client for custom resource definitions") + log.Fatal().Err(err).Msgf("Failed to create reconcile client for custom resource definitions") } } - // Initialize the crd conversion webhook server to support the conversion of OSM's CRDs - if err := crdconversion.NewConversionWebhook(ctx, crdClient, certManager, osmNamespace); err != nil { - events.GenericEventRecorder().FatalEvent(err, events.InitializationError, fmt.Sprintf("Error creating crd conversion webhook: %s", err)) - } - - version.SetMetric() /* * Initialize osm-bootstrap's HTTP server */ @@ -263,19 +220,66 @@ func main() { log.Fatal().Err(err).Msgf("Failed to start OSM metrics/probes HTTP server") } - if enableReconciler { - log.Info().Msgf("OSM reconciler enabled for custom resource definitions") - err = reconciler.NewReconcilerClient(kubeClient, apiServerClient, meshName, osmVersion, stop, reconciler.CrdInformerKey) - if err != nil { - events.GenericEventRecorder().FatalEvent(err, events.InitializationError, "Error creating reconciler client for custom resource definitions") - } - } - <-stop cancel() log.Info().Msgf("Stopping osm-bootstrap %s; %s; %s", version.Version, version.GitCommit, version.BuildDate) } +func applyOrUpdateCRDs(crdClient *apiclient.ApiextensionsV1Client) { + crdFiles, err := filepath.Glob("/osm-crds/*.yaml") + + if err != nil { + log.Fatal().Err(err).Msgf("error reading files from /osm-crds") + } + + scheme = runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + decode := codecs.UniversalDeserializer().Decode + + for _, file := range crdFiles { + yaml, err := os.ReadFile(filepath.Clean(file)) + if err != nil { + log.Fatal().Err(err).Msgf("Error reading CRD file %s", file) + } + + crd := &apiv1.CustomResourceDefinition{} + _, _, err = decode(yaml, nil, crd) + if err != nil { + log.Fatal().Err(err).Msgf("Error decoding CRD file %s", file) + } + + crd.Labels[constants.ReconcileLabel] = strconv.FormatBool(enableReconciler) + + crdExisting, err := crdClient.CustomResourceDefinitions().Get(context.Background(), crd.Name, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + log.Fatal().Err(err).Msgf("error getting CRD %s", crd.Name) + } + + if apierrors.IsNotFound(err) { + log.Info().Msgf("crds %s not found, creating CRD", crd.Name) + if err := util.CreateApplyAnnotation(crd, unstructured.UnstructuredJSONScheme); err != nil { + log.Fatal().Err(err).Msgf("Error applying annotation to CRD %s", crd.Name) + } + if _, err = crdClient.CustomResourceDefinitions().Create(context.Background(), crd, metav1.CreateOptions{}); err != nil { + log.Fatal().Err(err).Msgf("Error creating crd : %s", crd.Name) + } + log.Info().Msgf("Successfully created crd: %s", crd.Name) + } else { + log.Info().Msgf("Patching conversion webhook configuration for crd: %s, setting to \"None\"", crd.Name) + + crdExisting.Labels[constants.ReconcileLabel] = strconv.FormatBool(enableReconciler) + crdExisting.Spec = crd.Spec + crdExisting.Spec.Conversion = &apiv1.CustomResourceConversion{ + Strategy: apiv1.NoneConverter, + } + if _, err = crdClient.CustomResourceDefinitions().Update(context.Background(), crdExisting, metav1.UpdateOptions{}); err != nil { + log.Fatal().Err(err).Msgf("Error updating conversion webhook configuration for crd : %s", crd.Name) + } + log.Info().Msgf("successfully set conversion webhook configuration for crd : %s to \"None\"", crd.Name) + } + } +} + func (b *bootstrap) createDefaultMeshConfig() error { // find presets config map to build the default MeshConfig from that presetsConfigMap, err := b.kubeClient.CoreV1().ConfigMaps(b.namespace).Get(context.TODO(), presetMeshConfigName, metav1.GetOptions{}) diff --git a/dockerfiles/Dockerfile.osm-bootstrap b/dockerfiles/Dockerfile.osm-bootstrap index 45bc2447e1..a50285f525 100644 --- a/dockerfiles/Dockerfile.osm-bootstrap +++ b/dockerfiles/Dockerfile.osm-bootstrap @@ -21,3 +21,4 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ FROM $FINAL_BASE_IMAGE ENV GOFIPS=1 COPY --from=builder /osm/osm-bootstrap / +COPY ./cmd/osm-bootstrap/crds /osm-crds/ diff --git a/go.mod b/go.mod index 83b468d16e..c1222cb222 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,6 @@ require ( github.com/mholt/archiver/v3 v3.5.1 github.com/mitchellh/gox v1.0.1 github.com/mitchellh/hashstructure/v2 v2.0.1 - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/norwoodj/helm-docs v1.4.0 github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/ginkgo v1.16.5 diff --git a/go.sum b/go.sum index 30424b9c62..2c9e372223 100644 --- a/go.sum +++ b/go.sum @@ -1401,7 +1401,6 @@ github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1: github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/crd-schema-fuzz v1.0.0/go.mod h1:4z/rcm37JxUkSsExFcLL6ZIT1SgDRdLiu7qq1evdVS0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index d66d93f1b5..aa3eef7a01 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -147,9 +147,6 @@ const ( // OSMMeshConfig is the name of the OSM MeshConfig OSMMeshConfig = "osm-mesh-config" - - // CRDConversionWebhookPort is the port of the CRD conversion webhook service - CRDConversionWebhookPort = 9443 ) // HealthProbe constants diff --git a/pkg/crdconversion/config_meshconfig_conversion.go b/pkg/crdconversion/config_meshconfig_conversion.go deleted file mode 100644 index 9bac8c27ba..0000000000 --- a/pkg/crdconversion/config_meshconfig_conversion.go +++ /dev/null @@ -1,67 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveMeshConfigConversion servers endpoint for the converter defined as convertMeshConfig function. -func serveMeshConfigConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertMeshConfig) -} - -// convertMeshConfig contains the business logic to convert meshconfigs.config.openservicemesh.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertMeshConfig(obj *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := obj.DeepCopy() - fromVersion := obj.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("MeshConfig: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msgf("MeshConfig conversion request: from-version=%s, to-version=%s", fromVersion, toVersion) - switch fromVersion { - case "config.openservicemesh.io/v1alpha1": - switch toVersion { - case "config.openservicemesh.io/v1alpha2": - log.Debug().Msgf("Converting MeshConfig v1alpha1 -> v1alpha2") - // v1alpha2 is backward compatible with v1alpha1, so no conversion is - // necessary at this moment. - - default: - return nil, fmt.Errorf("Unexpected conversion to-version for MeshConfig resource: %s", toVersion) - } - - case "config.openservicemesh.io/v1alpha2": - switch toVersion { - case "config.openservicemesh.io/v1alpha1": - log.Debug().Msgf("Converting MeshConfig v1alpha2 -> v1alpha1") - // Remove spec.traffic.outboundIPRangeInclusionList field not supported in v1alpha1 - unsupportedFields := [][]string{ - {"spec", "traffic", "outboundIPRangeInclusionList"}, - {"spec", "sidecar", "tlsMinProtocolVersion"}, - {"spec", "sidecar", "tlsMaxProtocolVersion"}, - {"spec", "sidecar", "cipherSuites"}, - {"spec", "sidecar", "ecdhCurves"}, - } - - for _, unsupportedField := range unsupportedFields { - _, found, err := unstructured.NestedSlice(convertedObject.Object, unsupportedField...) - if found && err == nil { - unstructured.RemoveNestedField(convertedObject.Object, unsupportedField...) - } - } - default: - return nil, fmt.Errorf("Unexpected conversion to-version for MeshConfig resource: %s", toVersion) - } - - default: - return nil, fmt.Errorf("Unexpected conversion from-version for MeshConfig resource: %s", fromVersion) - } - - log.Debug().Msg("MeshConfig: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/config_meshconfig_conversion_test.go b/pkg/crdconversion/config_meshconfig_conversion_test.go deleted file mode 100644 index 0e442c16bf..0000000000 --- a/pkg/crdconversion/config_meshconfig_conversion_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package crdconversion - -import ( - "testing" - - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - - configv1alpha1 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha1" - configv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2" -) - -func TestConvertMeshConfig(t *testing.T) { - testCases := []struct { - name string - request runtime.Object - toVersion string - verifyFn func(*assert.Assertions, *unstructured.Unstructured, error) - }{ - { - name: "v1alpha2 -> v1alpha1 should remove additional field", - request: &configv1alpha2.MeshConfig{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "config.openservicemesh.io/v1alpha2", - Kind: "MeshConfig", - }, - Spec: configv1alpha2.MeshConfigSpec{ - Traffic: configv1alpha2.TrafficSpec{ - OutboundIPRangeInclusionList: []string{"1.1.1.1/32"}, - }, - Sidecar: configv1alpha2.SidecarSpec{ - TLSMinProtocolVersion: "TLSv1_2", - TLSMaxProtocolVersion: "TLSv1_3", - CipherSuites: []string{"SomeCipherSuite"}, - ECDHCurves: []string{"SomeECDHCurve"}, - }, - }, - }, - toVersion: "config.openservicemesh.io/v1alpha1", - verifyFn: func(a *assert.Assertions, converted *unstructured.Unstructured, err error) { - a.NoError(err) - - unsupportedFields := [][]string{ - {"spec", "traffic", "outboundIPRangeInclusionList"}, - {"spec", "sidecar", "tlsMinProtocolVersion"}, - {"spec", "sidecar", "tlsMaxProtocolVersion"}, - {"spec", "sidecar", "cipherSuites"}, - {"spec", "sidecar", "ecdhCurves"}, - } - - for _, unsupportedField := range unsupportedFields { - _, found, _ := unstructured.NestedSlice(converted.Object, unsupportedField...) - a.False(found) - } - }, - }, - { - name: "v1alpha1 -> v1alpha2", - request: &configv1alpha1.MeshConfig{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "config.openservicemesh.io/v1alpha1", - Kind: "MeshConfig", - }, - Spec: configv1alpha1.MeshConfigSpec{}, - }, - toVersion: "config.openservicemesh.io/v1alpha2", - verifyFn: func(a *assert.Assertions, converted *unstructured.Unstructured, err error) { - a.NoError(err) - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - a := assert.New(t) - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(tc.request) - a.Nil(err) - unstructuredReq := &unstructured.Unstructured{Object: obj} - converted, status := convertMeshConfig(unstructuredReq, tc.toVersion) - tc.verifyFn(a, converted, status) - }) - } -} diff --git a/pkg/crdconversion/crdconversion.go b/pkg/crdconversion/crdconversion.go deleted file mode 100644 index 0dcf7929cc..0000000000 --- a/pkg/crdconversion/crdconversion.go +++ /dev/null @@ -1,97 +0,0 @@ -package crdconversion - -import ( - "context" - "net/http" - - apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apiclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" - - "github.com/openservicemesh/osm/pkg/certificate" - "github.com/openservicemesh/osm/pkg/constants" - "github.com/openservicemesh/osm/pkg/webhook" -) - -const ( - // paths to convert CRD's - trafficAccessConverterPath = "/convert/trafficaccess" - httpRouteGroupConverterPath = "/convert/httproutegroup" - meshConfigConverterPath = "/convert/meshconfig" - egressPolicyConverterPath = "/convert/egresspolicy" - trafficSplitConverterPath = "/convert/trafficsplit" - tcpRoutesConverterPath = "/convert/tcproutes" - ingressBackendsPolicyConverterPath = "/convert/ingressbackendspolicy" - retryPolicyConverterPath = "/convert/retrypolicy" -) - -// apiKindToPath maps the resource API kind to the HTTP path at which -// the webhook server peforms the conversion -// *Note: only add API kinds for which conversion is necessary so that -// the webhook is not invoked otherwise. -var apiKindToPath = map[string]string{ - "meshconfigs.config.openservicemesh.io": meshConfigConverterPath, -} - -var conversionReviewVersions = []string{"v1beta1", "v1"} - -// NewConversionWebhook starts a new web server handling requests from the CRD's -func NewConversionWebhook(ctx context.Context, crdClient apiclient.ApiextensionsV1Interface, certManager *certificate.Manager, osmNamespace string) error { - srv := webhook.NewServer(constants.OSMBootstrapName, osmNamespace, constants.CRDConversionWebhookPort, certManager, map[string]http.HandlerFunc{ - meshConfigConverterPath: serveMeshConfigConversion, - trafficAccessConverterPath: serveTrafficAccessConversion, - httpRouteGroupConverterPath: serveHTTPRouteGroupConversion, - egressPolicyConverterPath: serveEgressPolicyConversion, - trafficSplitConverterPath: serveTrafficSplitConversion, - tcpRoutesConverterPath: serveTCPRouteConversion, - ingressBackendsPolicyConverterPath: serveIngressBackendsPolicyConversion, - retryPolicyConverterPath: serveRetryPolicyConversion, - }, func(cert *certificate.Certificate) error { - return patchCrds(cert, crdClient, osmNamespace) - }) - - return srv.Run(ctx) -} - -func patchCrds(cert *certificate.Certificate, crdClient apiclient.ApiextensionsV1Interface, osmNamespace string) error { - for crdName, crdConversionPath := range apiKindToPath { - if err := updateCrdConfiguration(cert, crdClient, osmNamespace, crdName, crdConversionPath); err != nil { - log.Error().Err(err).Msgf("Error updating conversion webhook configuration for crd : %s", crdName) - return err - } - } - return nil -} - -// updateCrdConfiguration updates the Conversion section of the CRD and adds a reconcile label if OSM's reconciler is enabled. -func updateCrdConfiguration(cert *certificate.Certificate, crdClient apiclient.ApiextensionsV1Interface, osmNamespace, crdName, crdConversionPath string) error { - crd, err := crdClient.CustomResourceDefinitions().Get(context.Background(), crdName, metav1.GetOptions{}) - if err != nil { - return err - } - - crd.Spec.Conversion = &apiv1.CustomResourceConversion{ - Strategy: apiv1.WebhookConverter, - Webhook: &apiv1.WebhookConversion{ - ClientConfig: &apiv1.WebhookClientConfig{ - Service: &apiv1.ServiceReference{ - Namespace: osmNamespace, - Name: constants.OSMBootstrapName, - Port: pointer.Int32(constants.CRDConversionWebhookPort), - Path: &crdConversionPath, - }, - CABundle: cert.GetTrustedCAs(), - }, - ConversionReviewVersions: conversionReviewVersions, - }, - } - - if _, err = crdClient.CustomResourceDefinitions().Update(context.Background(), crd, metav1.UpdateOptions{}); err != nil { - log.Error().Err(err).Msgf("Error updating conversion webhook configuration for crd : %s", crdName) - return err - } - - log.Info().Msgf("successfully updated conversion webhook configuration for crd : %s", crdName) - return nil -} diff --git a/pkg/crdconversion/crdconversion_test.go b/pkg/crdconversion/crdconversion_test.go deleted file mode 100644 index 64507d77bc..0000000000 --- a/pkg/crdconversion/crdconversion_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package crdconversion - -import ( - "context" - "testing" - "time" - - "github.com/golang/mock/gomock" - tassert "github.com/stretchr/testify/assert" - apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/openservicemesh/osm/pkg/certificate" - "github.com/openservicemesh/osm/pkg/certificate/pem" - tresorFake "github.com/openservicemesh/osm/pkg/certificate/providers/tresor/fake" - "github.com/openservicemesh/osm/pkg/constants" - "github.com/openservicemesh/osm/pkg/tests" -) - -func TestUpdateCrdConfiguration(t *testing.T) { - testCases := []struct { - name string - }{ - { - name: "base case", - }, - } - - var cert = &certificate.Certificate{ - CommonName: "", - CertChain: pem.Certificate("chain"), - PrivateKey: pem.PrivateKey("key"), - IssuingCA: pem.RootCertificate("ca"), - TrustedCAs: pem.RootCertificate("ca"), - Expiration: time.Now(), - SerialNumber: "serial_number", - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - assert := tassert.New(t) - - crdClient := fake.NewSimpleClientset(&apiv1.CustomResourceDefinition{ - TypeMeta: metav1.TypeMeta{ - Kind: "CustomResourceDefinition", - APIVersion: "apiextensions.k8s.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "tests.test.openservicemesh.io", - Labels: map[string]string{ - constants.OSMAppNameLabelKey: constants.OSMAppNameLabelValue, - }, - }, - Spec: apiv1.CustomResourceDefinitionSpec{ - Group: "test.openservicemesh.io", - Names: apiv1.CustomResourceDefinitionNames{ - Plural: "tests", - Singular: "test", - Kind: "test", - ListKind: "testList", - }, - Scope: apiv1.NamespaceScoped, - Versions: []apiv1.CustomResourceDefinitionVersion{{ - Name: "v1alpha1", - Served: true, - Storage: true, - Schema: &apiv1.CustomResourceValidation{ - OpenAPIV3Schema: &apiv1.JSONSchemaProps{ - Type: "object", - Properties: make(map[string]apiv1.JSONSchemaProps), - }, - }, - }}, - }, - }) - - err := updateCrdConfiguration(cert, crdClient.ApiextensionsV1(), tests.Namespace, "tests.test.openservicemesh.io", "/testconversion") - assert.Nil(err) - - crds, err := crdClient.ApiextensionsV1().CustomResourceDefinitions().List(context.TODO(), metav1.ListOptions{}) - assert.Nil(err) - - crd := crds.Items[0] - assert.Equal(crd.Spec.Conversion.Strategy, apiv1.WebhookConverter) - assert.Equal(crd.Spec.Conversion.Webhook.ClientConfig.CABundle, []byte("ca")) - assert.Equal(crd.Spec.Conversion.Webhook.ClientConfig.Service.Namespace, tests.Namespace) - assert.Equal(crd.Spec.Conversion.Webhook.ClientConfig.Service.Name, constants.OSMBootstrapName) - assert.Equal(crd.Spec.Conversion.Webhook.ConversionReviewVersions, conversionReviewVersions) - - assert.Equal(crd.Labels[constants.OSMAppNameLabelKey], constants.OSMAppNameLabelValue) - }) - } -} - -func TestNewConversionWebhook(t *testing.T) { - assert := tassert.New(t) - crdClient := fake.NewSimpleClientset() - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - - fakeCertManager := tresorFake.NewFake(1 * time.Hour) - osmNamespace := "-osm-namespace-" - - actualErr := NewConversionWebhook(context.Background(), crdClient.ApiextensionsV1(), fakeCertManager, osmNamespace) - assert.NotNil(actualErr) -} diff --git a/pkg/crdconversion/framework.go b/pkg/crdconversion/framework.go deleted file mode 100644 index 6a1b69c855..0000000000 --- a/pkg/crdconversion/framework.go +++ /dev/null @@ -1,193 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package crdconversion - -import ( - "fmt" - "io/ioutil" - "net/http" - "strconv" - "strings" - - "github.com/munnerz/goautoneg" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer/json" - - "github.com/openservicemesh/osm/pkg/metricsstore" -) - -// convertFunc is the user defined function for any conversion. The code in this file is a -// template that can be use for any CR conversion given this function. -type convertFunc func(Object *unstructured.Unstructured, version string) (*unstructured.Unstructured, error) - -// conversionResponseFailureWithMessagef is a helper function to create an AdmissionResponse -// with a formatted embedded error message. -func conversionResponseFailureWithMessagef(msg string, params ...interface{}) *v1beta1.ConversionResponse { - return &v1beta1.ConversionResponse{ - Result: metav1.Status{ - Message: fmt.Sprintf(msg, params...), - Status: metav1.StatusFailure, - }, - } -} - -// doConversion converts the requested object given the conversion function and returns a conversion response. -// failures will be reported as Reason in the conversion response. -func doConversion(convertRequest *v1beta1.ConversionRequest, convert convertFunc) *v1beta1.ConversionResponse { - var convertedObjects []runtime.RawExtension - // aggregate errors from all objects in the request vs. only returning the - // first so errors from all objects are sent in the request and metrics are - // recorded as accurately as possible. - var errs []string - for i, obj := range convertRequest.Objects { - cr := unstructured.Unstructured{} - if err := cr.UnmarshalJSON(obj.Raw); err != nil { - log.Error().Err(err).Msg("error unmarshalling object JSON") - errs = append(errs, fmt.Sprintf("failed to unmarshal object (%v) with error: %v", string(obj.Raw), err)) - continue - } - // Save the parsed object to read from later when metrics are recorded - convertRequest.Objects[i].Object = &cr - convertedCR, err := convert(&cr, convertRequest.DesiredAPIVersion) - if err != nil { - log.Error().Err(err).Msg("conversion failed") - errs = append(errs, err.Error()) - continue - } - convertedCR.SetAPIVersion(convertRequest.DesiredAPIVersion) - convertedObjects = append(convertedObjects, runtime.RawExtension{Object: convertedCR}) - } - - resp := &v1beta1.ConversionResponse{ - ConvertedObjects: convertedObjects, - Result: metav1.Status{ - Status: metav1.StatusSuccess, - }, - } - if len(errs) > 0 { - resp = &v1beta1.ConversionResponse{ - Result: metav1.Status{ - Message: strings.Join(errs, "; "), - Status: metav1.StatusFailure, - }, - } - } - return resp -} - -func serve(w http.ResponseWriter, r *http.Request, convert convertFunc) { - var body []byte - if r.Body != nil { - if data, err := ioutil.ReadAll(r.Body); err == nil { - body = data - } - } - - contentType := r.Header.Get("Content-Type") - serializer := getInputSerializer(contentType) - if serializer == nil { - msg := fmt.Sprintf("invalid Content-Type header `%s`", contentType) - log.Error().Msgf(msg) - http.Error(w, msg, http.StatusBadRequest) - return - } - - convertReview := v1beta1.ConversionReview{} - if _, _, err := serializer.Decode(body, nil, &convertReview); err != nil { - log.Error().Err(err).Msgf("failed to deserialize body (%v)", string(body)) - convertReview.Response = conversionResponseFailureWithMessagef("failed to deserialize body (%v) with error %v", string(body), err) - } else { - convertReview.Response = doConversion(convertReview.Request, convert) - convertReview.Response.UID = convertReview.Request.UID - } - - var success bool - if convertReview.Response != nil { - success = convertReview.Response.Result.Status == metav1.StatusSuccess - } - if convertReview.Request != nil { - toVersion := convertReview.Request.DesiredAPIVersion - for _, reqObj := range convertReview.Request.Objects { - var fromVersion string - var kind string - if reqObj.Object != nil && reqObj.Object.GetObjectKind() != nil { - fromVersion = reqObj.Object.GetObjectKind().GroupVersionKind().GroupVersion().String() - kind = reqObj.Object.GetObjectKind().GroupVersionKind().Kind - } - metricsstore.DefaultMetricsStore.ConversionWebhookResourceTotal.WithLabelValues(kind, fromVersion, toVersion, strconv.FormatBool(success)).Inc() - } - } - - log.Debug().Msgf(fmt.Sprintf("sending response: %v", convertReview.Response)) - - // reset the request, it is not needed in a response. - convertReview.Request = &v1beta1.ConversionRequest{} - - accept := r.Header.Get("Accept") - outSerializer := getOutputSerializer(accept) - if outSerializer == nil { - msg := fmt.Sprintf("invalid accept header `%s`", accept) - log.Error().Msgf(msg) - http.Error(w, msg, http.StatusBadRequest) - return - } - err := outSerializer.Encode(&convertReview, w) - if err != nil { - log.Error().Err(err).Msg("error encoding ConversionReview") - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -type mediaType struct { - Type, SubType string -} - -var scheme = runtime.NewScheme() -var serializers = map[mediaType]runtime.Serializer{ - {"application", "json"}: json.NewSerializer(json.DefaultMetaFactory, scheme, scheme, false), - {"application", "yaml"}: json.NewYAMLSerializer(json.DefaultMetaFactory, scheme, scheme), -} - -func getInputSerializer(contentType string) runtime.Serializer { - parts := strings.SplitN(contentType, "/", 2) - if len(parts) != 2 { - return nil - } - return serializers[mediaType{parts[0], parts[1]}] -} - -func getOutputSerializer(accept string) runtime.Serializer { - if len(accept) == 0 { - return serializers[mediaType{"application", "json"}] - } - - clauses := goautoneg.ParseAccept(accept) - for _, clause := range clauses { - for k, v := range serializers { - switch { - case clause.Type == k.Type && clause.SubType == k.SubType, - clause.Type == k.Type && clause.SubType == "*", - clause.Type == "*" && clause.SubType == "*": - return v - } - } - } - - return nil -} diff --git a/pkg/crdconversion/framework_test.go b/pkg/crdconversion/framework_test.go deleted file mode 100644 index d6061ff24c..0000000000 --- a/pkg/crdconversion/framework_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package crdconversion - -import ( - "bytes" - "encoding/json" - "errors" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - - "github.com/openservicemesh/osm/pkg/metricsstore" -) - -func TestServe(t *testing.T) { - runServe := func(req *v1beta1.ConversionRequest, convert convertFunc) (*httptest.ResponseRecorder, *v1beta1.ConversionReview) { - j, err := json.Marshal(&v1beta1.ConversionReview{ - Request: req, - }) - require.NoError(t, err) - body := bytes.NewBuffer(j) - r := httptest.NewRequest(http.MethodPost, "http://this.doesnt/matter", body) - r.Header.Add("Content-Type", "application/json") - r.Header.Add("Accept", "application/json") - w := httptest.NewRecorder() - - serve(w, r, convert) - - res := new(v1beta1.ConversionReview) - err = json.Unmarshal(w.Body.Bytes(), res) - require.NoError(t, err) - - return w, res - } - - metricsstore.DefaultMetricsStore.Start(metricsstore.DefaultMetricsStore.ConversionWebhookResourceTotal) - - req := &v1beta1.ConversionRequest{ - DesiredAPIVersion: "any.group/v1", - Objects: []runtime.RawExtension{ - { - Raw: []byte(`{ - "apiVersion": "any.group/v2", - "kind": "SomeKind" - }`), - }, - { - Raw: []byte(`{ - "apiVersion": "any.group/v3", - "kind": "SomeKind" - }`), - }, - }, - } - failConvert := func(*unstructured.Unstructured, string) (*unstructured.Unstructured, error) { - return nil, errors.New("fail") - } - okConvert := func(in *unstructured.Unstructured, _ string) (*unstructured.Unstructured, error) { - return in.DeepCopy(), nil - } - v2FailV3OkConvert := func(in *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - switch in.GetAPIVersion() { - case "any.group/v2": - return failConvert(in, toVersion) - case "any.group/v3": - return okConvert(in, toVersion) - } - panic("unexpected API version") - } - - a := assert.New(t) - - // ok conversion - w, res := runServe(req, okConvert) - - a.Equal(http.StatusOK, w.Result().StatusCode) - a.Equal(metav1.StatusSuccess, res.Response.Result.Status) - a.Len(res.Response.ConvertedObjects, 2) - - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v2",kind="SomeKind",success="true",to_version="any.group/v1"} 1` + "\n")) - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v3",kind="SomeKind",success="true",to_version="any.group/v1"} 1` + "\n")) - - // failing conversion - w, res = runServe(req, failConvert) - - a.Equal(http.StatusOK, w.Result().StatusCode) - a.Equal(metav1.StatusFailure, res.Response.Result.Status) - a.Len(res.Response.ConvertedObjects, 0) - a.Equal("fail; fail", res.Response.Result.Message) - - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v2",kind="SomeKind",success="false",to_version="any.group/v1"} 1` + "\n")) - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v3",kind="SomeKind",success="false",to_version="any.group/v1"} 1` + "\n")) - - // partially successful conversion - w, res = runServe(req, v2FailV3OkConvert) - - a.Equal(http.StatusOK, w.Result().StatusCode) - a.Equal(metav1.StatusFailure, res.Response.Result.Status) - a.Len(res.Response.ConvertedObjects, 0) - a.Equal("fail", res.Response.Result.Message) - - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v2",kind="SomeKind",success="false",to_version="any.group/v1"} 2` + "\n")) - a.True(metricsstore.DefaultMetricsStore.Contains(`osm_conversion_webhook_resource_total{from_version="any.group/v3",kind="SomeKind",success="false",to_version="any.group/v1"} 2` + "\n")) -} - -func TestDoConversionBadObjectJSON(t *testing.T) { - req := &v1beta1.ConversionRequest{ - DesiredAPIVersion: "any.group/v1", - Objects: []runtime.RawExtension{ - { - Raw: []byte(`{`), - }, - { - Raw: []byte(`{ - "apiVersion": "any.group/v3", - "kind": "SomeKind" - }`), - }, - }, - } - okConvert := func(in *unstructured.Unstructured, _ string) (*unstructured.Unstructured, error) { - return in.DeepCopy(), nil - } - - res := doConversion(req, okConvert) - - a := assert.New(t) - - a.Equal(metav1.StatusFailure, res.Result.Status) - a.Contains(res.Result.Message, "unexpected end of JSON input") - // Remaining objects still get parsed - a.NotNil(req.Objects[1].Object) -} diff --git a/pkg/crdconversion/policy_egress_conversion.go b/pkg/crdconversion/policy_egress_conversion.go deleted file mode 100644 index 067f9a3ec1..0000000000 --- a/pkg/crdconversion/policy_egress_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveEgressPolicyConversion servers endpoint for the converter defined as convertEgressPolicy function. -func serveEgressPolicyConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertEgressPolicy) -} - -// convertEgressPolicy contains the business logic to convert egresses.policy.openservicemesh.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertEgressPolicy(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("EgressPolicy: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("EgressPolicy: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/policy_ingressbackends_conversion.go b/pkg/crdconversion/policy_ingressbackends_conversion.go deleted file mode 100644 index 96ea4ff200..0000000000 --- a/pkg/crdconversion/policy_ingressbackends_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveIngressBackendsPolicyConversion servers endpoint for the converter defined as convertIngressBackendsPolicy function. -func serveIngressBackendsPolicyConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertIngressBackendsPolicy) -} - -// convertIngressBackendsPolicy contains the business logic to convert ingressbackends.policy.openservicemesh.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertIngressBackendsPolicy(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("IngressBackendsPolicy: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("IngressBackendsPolicy: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/policy_retry_conversion.go b/pkg/crdconversion/policy_retry_conversion.go deleted file mode 100644 index 986671701a..0000000000 --- a/pkg/crdconversion/policy_retry_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveRetryPolicyConversion servers endpoint for the converter defined as convertRetryPolicy function. -func serveRetryPolicyConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertRetryPolicy) -} - -// convertRetryPolicy contains the business logic to convert retries.policy.openservicemesh.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertRetryPolicy(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("RetryPolicy: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("RetryPolicy: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/smi_httproutegroup_conversion.go b/pkg/crdconversion/smi_httproutegroup_conversion.go deleted file mode 100644 index b61832353e..0000000000 --- a/pkg/crdconversion/smi_httproutegroup_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveHTTPRouteGroupConversion servers endpoint for the converter defined as convertHTTPRouteGroup function. -func serveHTTPRouteGroupConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertHTTPRouteGroup) -} - -// convertEgressPolicy contains the business logic to convert httproutegroups.specs.smi-spec.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertHTTPRouteGroup(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("HTTPRouteGroup: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("HTTPRouteGroup: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/smi_tcproutes_conversion.go b/pkg/crdconversion/smi_tcproutes_conversion.go deleted file mode 100644 index 7c4331ce82..0000000000 --- a/pkg/crdconversion/smi_tcproutes_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveTCPRouteConversion servers endpoint for the converter defined as convertTCPRoute function. -func serveTCPRouteConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertTCPRoute) -} - -// convertTCPRoute contains the business logic to convert tcproutes.specs.smi-spec.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertTCPRoute(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("TCPRoute: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Info().Msgf("TCPRoute: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/smi_trafficaccess_conversion.go b/pkg/crdconversion/smi_trafficaccess_conversion.go deleted file mode 100644 index d940c2add3..0000000000 --- a/pkg/crdconversion/smi_trafficaccess_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveTrafficAccessConversion servers endpoint for the converter defined as convertTrafficAccess function. -func serveTrafficAccessConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertTrafficAccess) -} - -// convertTrafficAccess contains the business logic to convert traffictargets.access.smi-spec.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertTrafficAccess(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("TrafficAccess: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("TrafficAccess: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/smi_trafficsplit_conversion.go b/pkg/crdconversion/smi_trafficsplit_conversion.go deleted file mode 100644 index 121fded8d6..0000000000 --- a/pkg/crdconversion/smi_trafficsplit_conversion.go +++ /dev/null @@ -1,27 +0,0 @@ -package crdconversion - -import ( - "fmt" - "net/http" - - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -) - -// serveTrafficSplitConversion servers endpoint for the converter defined as convertTrafficSplit function. -func serveTrafficSplitConversion(w http.ResponseWriter, r *http.Request) { - serve(w, r, convertTrafficSplit) -} - -// convertTrafficSplit contains the business logic to convert trafficsplits.access.smi-spec.io CRD -// Example implementation reference : https://github.com/kubernetes/kubernetes/blob/release-1.22/test/images/agnhost/crd-conversion-webhook/converter/example_converter.go -func convertTrafficSplit(Object *unstructured.Unstructured, toVersion string) (*unstructured.Unstructured, error) { - convertedObject := Object.DeepCopy() - fromVersion := Object.GetAPIVersion() - - if toVersion == fromVersion { - return nil, fmt.Errorf("TrafficSplit: conversion from a version to itself should not call the webhook: %s", toVersion) - } - - log.Debug().Msg("TrafficSplit: successfully converted object") - return convertedObject, nil -} diff --git a/pkg/crdconversion/types.go b/pkg/crdconversion/types.go deleted file mode 100644 index 51ff239591..0000000000 --- a/pkg/crdconversion/types.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package crdconversion implements OSM's CRD conversion facility. The crd-converter webhook -// server intercepts crd get/list/create/update requests to apply the required conversion logic. -package crdconversion - -import ( - "github.com/openservicemesh/osm/pkg/logger" -) - -var log = logger.New("crd-conversion") diff --git a/pkg/metricsstore/metricsstore.go b/pkg/metricsstore/metricsstore.go index 90c59d2fc9..c898166239 100644 --- a/pkg/metricsstore/metricsstore.go +++ b/pkg/metricsstore/metricsstore.go @@ -62,10 +62,6 @@ type MetricsStore struct { // generated for both validating and mutating webhooks AdmissionWebhookResponseTotal *prometheus.CounterVec - // ConversionWebhookResponseTotal counts the resources converted by - // conversion webhooks - ConversionWebhookResourceTotal *prometheus.CounterVec - /* * Certificate metrics */ @@ -209,12 +205,6 @@ func init() { Help: "Counter for responses sent by admission webhooks", }, []string{"kind", "success"}) - defaultMetricsStore.ConversionWebhookResourceTotal = prometheus.NewCounterVec(prometheus.CounterOpts{ - Namespace: metricsRootNamespace, - Name: "conversion_webhook_resource_total", - Help: "Counter for resources converted by conversion webhooks", - }, []string{"kind", "from_version", "to_version", "success"}) - /* * Certificate metrics */