diff --git a/Makefile b/Makefile index b79b4e0..333055d 100644 --- a/Makefile +++ b/Makefile @@ -221,7 +221,7 @@ $(ENVTEST): $(LOCALBIN) bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files. operator-sdk generate kustomize manifests -q cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS) + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS) operator-sdk bundle validate ./bundle .PHONY: bundle-build diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index ba8dcfc..441bb25 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -22,6 +22,7 @@ rules: - persistentvolumeclaims - pods - secrets + - serviceaccounts - services - services/finalizers verbs: @@ -65,6 +66,18 @@ rules: verbs: - create - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - route.openshift.io resources: @@ -81,6 +94,7 @@ rules: - apiGroups: - security.openshift.io resourceNames: + - anyuid - nonroot resources: - securitycontextconstraints diff --git a/controllers/app.go b/controllers/app.go index b9caa57..35b9bc7 100644 --- a/controllers/app.go +++ b/controllers/app.go @@ -4,9 +4,34 @@ import ( hyperfoilv1alpha1 "github.com/Hyperfoil/horreum-operator/api/v1alpha1" routev1 "github.com/openshift/api/route/v1" corev1 "k8s.io/api/core/v1" + // rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func appinitConfigMap(cr *hyperfoilv1alpha1.Horreum) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + "-app-init", + Namespace: cr.Namespace, + Labels: map[string]string{ + "app": cr.Name, + }, + }, + Data: map[string]string{ + // Note: 0.7.11 of Horreum used here still has grafana in the k8s-setup.sh script + "app_init.sh": ` + echo 'Injecting service-ca certificate ...' + keytool -noprompt -import -alias service-ca -file /etc/ssl/certs/service-ca.crt -cacerts -storepass changeit + until cat /deployments/k8s-setup.sh | sed '/grafana/d' | sh -x + do + echo 'Re-trying init ...' + sleep 10 + done + `, + }, + } +} + func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl string) *corev1.Pod { keycloakInternalURL := keycloakInternalURL(cr) @@ -58,6 +83,17 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin }) } volumes := []corev1.Volume{ + { + Name: "app-init", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-app-init", + }, + DefaultMode: func(i int32) *int32 { return &i }(0555), + }, + }, + }, { Name: "imports", VolumeSource: corev1.VolumeSource{ @@ -115,7 +151,9 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin if routeType == "reencrypt" || routeType == "" { caCertArg = "--cacert /etc/ssl/certs/service-ca.crt" } + // userId := int64(0) return &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ Name: cr.Name + "-app", Namespace: cr.Namespace, @@ -125,14 +163,18 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin }, }, Spec: corev1.PodSpec{ + // ServiceAccountName: "horreum-init", TerminationGracePeriodSeconds: &[]int64{0}[0], InitContainers: []corev1.Container{ { Name: "init", Image: appImage(cr), ImagePullPolicy: corev1.PullAlways, + // SecurityContext: &corev1.SecurityContext{ + // RunAsUser: &[]int64{userId}[0], + // }, Command: []string{ - "sh", "-x", "-c", "/deployments/k8s-setup.sh", + "sh", "-x", "-c", "/deployments/app_init.sh;", }, Env: []corev1.EnvVar{ secretEnv("KEYCLOAK_USER", keycloakAdminSecret(cr), corev1.BasicAuthUsernameKey), @@ -153,6 +195,11 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin }, }, VolumeMounts: []corev1.VolumeMount{ + { + Name: "app-init", + MountPath: "/deployments/app_init.sh", + SubPath: "app_init.sh", + }, { Name: "imports", MountPath: "/etc/horreum/imports", @@ -171,7 +218,6 @@ func appPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl, appPublicUrl strin Image: appImage(cr), Command: []string{ "sh", "-c", ` - keytool -noprompt -import -alias service-ca -file /etc/ssl/certs/service-ca.crt -cacerts -storepass changeit export QUARKUS_OIDC_CREDENTIALS_SECRET=$$(cat /etc/horreum/imports/clientsecret) /deployments/horreum.sh `, @@ -210,3 +256,56 @@ func appService(cr *hyperfoilv1alpha1.Horreum, r *HorreumReconciler) *corev1.Ser func appRoute(cr *hyperfoilv1alpha1.Horreum, r *HorreumReconciler) (*routev1.Route, error) { return route(cr.Spec.Route, "", cr, r) } + +func appServiceAccount(cr *hyperfoilv1alpha1.Horreum) *corev1.ServiceAccount { + return &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "horreum-init", + Namespace: cr.Namespace, + }, + } +} + +// func appClusterRole(cr *hyperfoilv1alpha1.Horreum) *rbacv1.ClusterRole { +// return &rbacv1.ClusterRole{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: "horreum-init-cluster-role", +// }, +// Rules: []rbacv1.PolicyRule{ +// { +// APIGroups: []string{ +// "security.openshift.io", +// }, +// ResourceNames: []string{ +// "anyuid", +// }, +// Resources: []string{ +// "securitycontextconstraints", +// }, +// Verbs: []string{ +// "use", +// }, +// }, +// }, +// } +// } + +// func appClusterRoleBinding(cr *hyperfoilv1alpha1.Horreum) *rbacv1.ClusterRoleBinding { +// return &rbacv1.ClusterRoleBinding{ +// ObjectMeta: metav1.ObjectMeta{ +// Name: "horreum-init-cluster-role-binding", +// }, +// RoleRef: rbacv1.RoleRef{ +// APIGroup: "rbac.authorization.k8s.io", +// Kind: "ClusterRole", +// Name: "horreum-init-cluster-role", +// }, +// Subjects: []rbacv1.Subject{ +// { +// Kind: "ServiceAccount", +// Name: "horreum-init", +// Namespace: cr.Namespace, +// }, +// }, +// } +// } diff --git a/controllers/horreum_controller.go b/controllers/horreum_controller.go index cf1b859..679efa1 100644 --- a/controllers/horreum_controller.go +++ b/controllers/horreum_controller.go @@ -34,6 +34,7 @@ import ( routev1 "github.com/openshift/api/route/v1" corev1 "k8s.io/api/core/v1" + // rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -63,7 +64,8 @@ var nocheck = func(interface{}) (bool, string, string) { //+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums/status,verbs=get;update;patch //+kubebuilder:rbac:groups=hyperfoil.io,resources=horreums/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=core,resources=pods;services;services/finalizers;endpoints;persistentvolumeclaims;events;configmaps;secrets;serviceaccounts,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;create //+kubebuilder:rbac:groups=apps,resourceNames=horreum-operator,resources=deployments/finalizers,verbs=update //+kubebuilder:rbac:groups=route.openshift.io,resources=routes;routes/custom-host,verbs=get;list;watch;create;update;patch;delete @@ -225,6 +227,10 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request) } cr.Status.KeycloakUrl = keycloakPublicUrl + keycloakConfigMap := keycloakConfigMap(cr) + if err := ensureSame(r, cr, logger, keycloakConfigMap, &corev1.ConfigMap{}, compareConfigMap, nocheck); err != nil { + return reconcile.Result{}, err + } keycloakPod := keycloakPod(cr, keycloakPublicUrl) if cr.Spec.Keycloak.External.PublicUri != "" { if err := ensureDeleted(r, cr, keycloakPod, &corev1.Pod{}); err != nil { @@ -238,10 +244,16 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request) return reconcile.Result{}, err } } - } else if err := ensureSame(r, cr, logger, keycloakPod, &corev1.Pod{}, comparePods, checkPod); err != nil { - return reconcile.Result{}, err + } else { + if err := ensureSame(r, cr, logger, keycloakPod, &corev1.Pod{}, comparePods, checkPod); err != nil { + return reconcile.Result{}, err + } } + appinitConfigMap := appinitConfigMap(cr) + if err := ensureSame(r, cr, logger, appinitConfigMap, &corev1.ConfigMap{}, compareConfigMap, nocheck); err != nil { + return reconcile.Result{}, err + } appService := appService(cr, r) appRoute, err := appRoute(cr, r) if err != nil { @@ -282,6 +294,18 @@ func (r *HorreumReconciler) Reconcile(ctx context.Context, request ctrl.Request) } cr.Status.PublicUrl = appPublicUrl + appServiceAccount := appServiceAccount(cr) + if err := ensureSame(r, cr, logger, appServiceAccount, &corev1.ServiceAccount{}, nocompare, nocheck); err != nil { + return reconcile.Result{}, err + } + // appClusterRole := appClusterRole(cr) + // if err := ensureSame(r, cr, logger, appClusterRole, &rbacv1.ClusterRole{}, nocompare, nocheck); err != nil { + // return reconcile.Result{}, err + // } + // appClusterRoleBinding := appClusterRoleBinding(cr) + // if err := ensureSame(r, cr, logger, appClusterRoleBinding, &rbacv1.ClusterRoleBinding{}, nocompare, nocheck); err != nil { + // return reconcile.Result{}, err + // } appPod := appPod(cr, keycloakPublicUrl, appPublicUrl) if err := ensureSame(r, cr, logger, appPod, &corev1.Pod{}, comparePods, checkPod); err != nil { return reconcile.Result{}, err diff --git a/controllers/keycloak.go b/controllers/keycloak.go index c7b94d0..3bf2092 100644 --- a/controllers/keycloak.go +++ b/controllers/keycloak.go @@ -2,6 +2,8 @@ package horreum import ( "errors" + "io" + "net/http" "net/url" hyperfoilv1alpha1 "github.com/Hyperfoil/horreum-operator/api/v1alpha1" @@ -11,6 +13,38 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) +func keycloakConfigMap(cr *hyperfoilv1alpha1.Horreum) *corev1.ConfigMap { + req, err := http.NewRequest("GET", "https://raw.githubusercontent.com/Hyperfoil/Horreum/0.7.11/infra/keycloak-horreum.json", nil) + if err != nil { + return nil + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil + } + + defer resp.Body.Close() + + horreumRealm, err := io.ReadAll(resp.Body) + if err != nil { + return nil + } + + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: cr.Name + "-keycloak-horreum-realm", + Namespace: cr.Namespace, + Labels: map[string]string{ + "app": cr.Name, + }, + }, + Data: map[string]string{ + "keycloak-horreum.json": string(horreumRealm), + }, + } +} + func keycloakPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl string) *corev1.Pod { secretName := cr.Name + "-keycloak-certs" if cr.Spec.Keycloak.Route.Type == "passthrough" { @@ -30,12 +64,26 @@ func keycloakPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl string) *corev }, }, }, + { + Name: "keycloak-horreum-realm", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cr.Name + "-keycloak-horreum-realm", + }, + }, + }, + }, } volumeMounts := []corev1.VolumeMount{ { Name: "certs", MountPath: "/etc/x509/https", }, + { + Name: "keycloak-horreum-realm", + MountPath: "/opt/keycloak/data/import", + }, } return &corev1.Pod{ @@ -48,10 +96,15 @@ func keycloakPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl string) *corev }, }, Spec: corev1.PodSpec{ - Containers: []corev1.Container{ + TerminationGracePeriodSeconds: &[]int64{0}[0], + InitContainers: []corev1.Container{ { - Name: "keycloak", - Image: withDefault(cr.Spec.Keycloak.Image, "quay.io/hyperfoil/horreum-keycloak:latest"), + Name: "init", + Image: withDefault(cr.Spec.Keycloak.Image, "quay.io/keycloak/keycloak:latest"), + ImagePullPolicy: corev1.PullAlways, + Args: []string{ + "build", + }, Env: []corev1.EnvVar{ secretEnv("KEYCLOAK_ADMIN", keycloakAdminSecret(cr), corev1.BasicAuthUsernameKey), secretEnv("KEYCLOAK_ADMIN_PASSWORD", keycloakAdminSecret(cr), corev1.BasicAuthPasswordKey), @@ -94,10 +147,59 @@ func keycloakPod(cr *hyperfoilv1alpha1.Horreum, keycloakPublicUrl string) *corev }, secretEnv("KC_DB_USERNAME", keycloakDbSecret(cr), corev1.BasicAuthUsernameKey), secretEnv("KC_DB_PASSWORD", keycloakDbSecret(cr), corev1.BasicAuthPasswordKey), + }, + VolumeMounts: volumeMounts, + }, + }, + Containers: []corev1.Container{ + { + Name: "keycloak", + Image: withDefault(cr.Spec.Keycloak.Image, "quay.io/keycloak/keycloak:latest"), + Args: []string{ + "start", "--optimized", "--import-realm", + }, + Env: []corev1.EnvVar{ + secretEnv("KEYCLOAK_ADMIN", keycloakAdminSecret(cr), corev1.BasicAuthUsernameKey), + secretEnv("KEYCLOAK_ADMIN_PASSWORD", keycloakAdminSecret(cr), corev1.BasicAuthPasswordKey), + { + Name: "DB_ADDR", + Value: withDefault(cr.Spec.Keycloak.Database.Host, dbDefaultHost(cr)), + }, + { + Name: "DB_PORT", + Value: withDefaultInt(cr.Spec.Keycloak.Database.Port, 5432), + }, + { + Name: "DB_DATABASE", + Value: withDefault(cr.Spec.Keycloak.Database.Name, "keycloak"), + }, + // For simplicity of development the image has HTTP enabled, which is not suitable for production + { + Name: "KC_HTTP_ENABLED", + Value: "false", + }, { - Name: "KEYCLOAK_COMMAND", - Value: "start", + Name: "KC_HTTPS_PORT", + Value: "8443", + }, + { + Name: "KC_HTTPS_CERTIFICATE_FILE", + Value: "/etc/x509/https/tls.crt", + }, + { + Name: "KC_HTTPS_CERTIFICATE_KEY_FILE", + Value: "/etc/x509/https/tls.key", }, + { + Name: "KC_HOSTNAME", + Value: publicUrl.Host, + }, + { + Name: "KC_PROXY", + Value: "passthrough", // TODO at least for NodePort? + }, + secretEnv("KC_DB_USERNAME", keycloakDbSecret(cr), corev1.BasicAuthUsernameKey), + secretEnv("KC_DB_PASSWORD", keycloakDbSecret(cr), corev1.BasicAuthPasswordKey), }, Ports: []corev1.ContainerPort{ { diff --git a/go.mod b/go.mod index d87cbb3..fd7e7cb 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,6 @@ require ( github.com/go-openapi/swag v0.19.14 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.2.0 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect @@ -45,7 +44,6 @@ require ( github.com/imdario/mergo v0.3.12 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/llparse/controller-gen v0.0.0-20180131011002-7a38c4658cb4 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -62,14 +60,12 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.21.0 // indirect golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect - golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/term v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect - golang.org/x/tools v0.7.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.0 // indirect @@ -78,9 +74,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.25.0 // indirect - k8s.io/code-generator v0.25.0 // indirect k8s.io/component-base v0.25.0 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect k8s.io/klog/v2 v2.70.1 // indirect k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect diff --git a/go.sum b/go.sum index 1bae09d..62a4a86 100644 --- a/go.sum +++ b/go.sum @@ -163,7 +163,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -282,8 +281,6 @@ 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= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/llparse/controller-gen v0.0.0-20180131011002-7a38c4658cb4 h1:FrJSY29TdNaLpfbneg37XwwmbPfJJsqkqmlBNVrsZ/0= -github.com/llparse/controller-gen v0.0.0-20180131011002-7a38c4658cb4/go.mod h1:MNU/rtrt2+D702OLCXO7CdoiLROp61B1U7JFmmgzIkM= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= @@ -444,8 +441,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -660,7 +655,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -845,14 +839,10 @@ k8s.io/apimachinery v0.25.1/go.mod h1:hqqA1X0bsgsxI6dXsJ4HnNTBOmJNxyPp8dw3u2fSHw k8s.io/client-go v0.25.1 h1:uFj4AJKtE1/ckcSKz8IhgAuZTdRXZDKev8g387ndD58= k8s.io/client-go v0.25.1/go.mod h1:rdFWTLV/uj2C74zGbQzOsmXPUtMAjSf7ajil4iJUNKo= k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= -k8s.io/code-generator v0.25.0 h1:QP8fJuXu882ztf6dsqJsso/Btm94pMd68TAZC1rE6KI= -k8s.io/code-generator v0.25.0/go.mod h1:B6jZgI3DvDFAualltPitbYMQ74NjaCFxum3YeKZZ+3w= k8s.io/component-base v0.25.0 h1:haVKlLkPCFZhkcqB6WCvpVxftrg6+FK5x1ZuaIDaQ5Y= k8s.io/component-base v0.25.0/go.mod h1:F2Sumv9CnbBlqrpdf7rKZTmmd2meJq0HizeyY/yAFxk= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=