diff --git a/assets/cabundle_cm.yaml b/assets/cabundle_cm.yaml index 6e57333cd..b795559b8 100644 --- a/assets/cabundle_cm.yaml +++ b/assets/cabundle_cm.yaml @@ -4,4 +4,4 @@ metadata: labels: config.openshift.io/inject-trusted-cabundle: "true" name: aws-ebs-csi-driver-trusted-ca-bundle - namespace: openshift-cluster-csi-drivers + namespace: ${NAMESPACE} diff --git a/assets/controller.yaml b/assets/controller.yaml index 39b4196d9..10977accd 100644 --- a/assets/controller.yaml +++ b/assets/controller.yaml @@ -2,7 +2,7 @@ kind: Deployment apiVersion: apps/v1 metadata: name: aws-ebs-csi-driver-controller - namespace: openshift-cluster-csi-drivers + namespace: ${NAMESPACE} annotations: config.openshift.io/inject-proxy: csi-driver config.openshift.io/inject-proxy-cabundle: csi-driver @@ -20,7 +20,6 @@ spec: labels: app: aws-ebs-csi-driver-controller spec: - hostNetwork: true serviceAccount: aws-ebs-csi-driver-controller-sa priorityClassName: system-cluster-critical nodeSelector: @@ -46,6 +45,7 @@ spec: image: ${DRIVER_IMAGE} imagePullPolicy: IfNotPresent args: + - controller - --endpoint=$(CSI_ENDPOINT) - --k8s-tag-cluster-id=${CLUSTER_ID} - --logtostderr @@ -132,6 +132,7 @@ spec: - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=openshift-cluster-csi-drivers - --v=${LOG_LEVEL} env: - name: ADDRESS @@ -176,6 +177,7 @@ spec: - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=openshift-cluster-csi-drivers - --v=${LOG_LEVEL} env: - name: ADDRESS @@ -219,6 +221,7 @@ spec: - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=openshift-cluster-csi-drivers - --v=${LOG_LEVEL} env: - name: ADDRESS @@ -261,6 +264,7 @@ spec: - --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION} - --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE} - --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD} + - --leader-election-namespace=openshift-cluster-csi-drivers - --v=${LOG_LEVEL} env: - name: ADDRESS diff --git a/assets/controller_pdb.yaml b/assets/controller_pdb.yaml index 99f9049d1..c8afff868 100644 --- a/assets/controller_pdb.yaml +++ b/assets/controller_pdb.yaml @@ -2,7 +2,7 @@ apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: aws-ebs-csi-driver-controller-pdb - namespace: openshift-cluster-csi-drivers + namespace: ${NAMESPACE} spec: maxUnavailable: 1 selector: diff --git a/assets/controller_sa.yaml b/assets/controller_sa.yaml index 2af4dd44b..22ff34d2e 100644 --- a/assets/controller_sa.yaml +++ b/assets/controller_sa.yaml @@ -2,4 +2,4 @@ apiVersion: v1 kind: ServiceAccount metadata: name: aws-ebs-csi-driver-controller-sa - namespace: openshift-cluster-csi-drivers + namespace: ${NAMESPACE} diff --git a/assets/node.yaml b/assets/node.yaml index cfd7e07f5..e05da26d6 100644 --- a/assets/node.yaml +++ b/assets/node.yaml @@ -33,6 +33,7 @@ spec: image: ${DRIVER_IMAGE} imagePullPolicy: IfNotPresent args: + - node - --endpoint=$(CSI_ENDPOINT) - --logtostderr - --v=${LOG_LEVEL} diff --git a/assets/rbac/controller_privileged_binding.yaml b/assets/rbac/controller_privileged_binding.yaml deleted file mode 100644 index 78b893112..000000000 --- a/assets/rbac/controller_privileged_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: ebs-controller-privileged-binding -subjects: - - kind: ServiceAccount - name: aws-ebs-csi-driver-controller-sa - namespace: openshift-cluster-csi-drivers -roleRef: - kind: ClusterRole - name: ebs-privileged-role - apiGroup: rbac.authorization.k8s.io diff --git a/cmd/aws-ebs-csi-driver-operator/main.go b/cmd/aws-ebs-csi-driver-operator/main.go index b2b89864f..3b091f5f3 100644 --- a/cmd/aws-ebs-csi-driver-operator/main.go +++ b/cmd/aws-ebs-csi-driver-operator/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "os" "github.com/openshift/library-go/pkg/controller/controllercmd" @@ -17,6 +18,8 @@ func main() { os.Exit(code) } +var guestKubeconfig *string + func NewOperatorCommand() *cobra.Command { cmd := &cobra.Command{ Use: "aws-ebs-csi-driver-operator", @@ -30,8 +33,12 @@ func NewOperatorCommand() *cobra.Command { ctrlCmd := controllercmd.NewControllerCommandConfig( "aws-ebs-csi-driver-operator", version.Get(), - operator.RunOperator, + // operator.RunOperator, + runOperatorWithGuestKubeconfig, ).NewCommand() + + guestKubeconfig = ctrlCmd.Flags().String("guest-kubeconfig", "", "Path to the guest kubeconfig file. This flag enables hypershift integration.") + ctrlCmd.Use = "start" ctrlCmd.Short = "Start the AWS EBS CSI Driver Operator" @@ -39,3 +46,7 @@ func NewOperatorCommand() *cobra.Command { return cmd } + +func runOperatorWithGuestKubeconfig(ctx context.Context, controllerConfig *controllercmd.ControllerContext) error { + return operator.RunOperator(ctx, controllerConfig, *guestKubeconfig) +} diff --git a/go.mod b/go.mod index a71ead531..329afcf7b 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,19 @@ go 1.18 require ( github.com/go-logr/logr v1.2.3 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/go-cmp v0.5.6 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/openshift/api v0.0.0-20220919112502-5eaf4250c423 github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d github.com/openshift/client-go v0.0.0-20220915152853-9dfefb19db2e - github.com/openshift/library-go v0.0.0-20221017091500-9aea380195f4 + github.com/openshift/library-go v0.0.0-20221017195819-7f7c08fa1941 github.com/prometheus/client_golang v1.12.1 github.com/spf13/cobra v1.4.0 golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect - k8s.io/api v0.25.1 - k8s.io/apimachinery v0.25.1 - k8s.io/client-go v0.25.1 - k8s.io/component-base v0.25.1 + k8s.io/api v0.25.0 + k8s.io/apimachinery v0.25.0 + k8s.io/client-go v0.25.0 + k8s.io/component-base v0.25.0 k8s.io/klog/v2 v2.80.1 k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect diff --git a/go.sum b/go.sum index cbfe6ae3e..9d2200972 100644 --- a/go.sum +++ b/go.sum @@ -264,9 +264,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -385,18 +384,18 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/openshift/api v0.0.0-20220919112502-5eaf4250c423 h1:6fJUUaZPDaTFCFLZ8ZgdaVaclzmerN6lb9ya17O3GGo= github.com/openshift/api v0.0.0-20220919112502-5eaf4250c423/go.mod h1:HJAEIh4gLXPDdWxgCbvmJjzd9QIxyPZJtPU0u2W4vH4= github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d h1:RR4ah7FfaPR1WePizm0jlrsbmPu91xQZnAsVVreQV1k= github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20220915152853-9dfefb19db2e h1:ab+BJg7h50pi2/rbMkDSXfYx8w80HLmr7NBs8H1hEvU= github.com/openshift/client-go v0.0.0-20220915152853-9dfefb19db2e/go.mod h1:e+TTiBDGWB3O3p3iAzl054x3cZDWhrZ5+jxJRCdEFkA= -github.com/openshift/library-go v0.0.0-20221017091500-9aea380195f4 h1:4P+w+CZsPS423+31zAQ814+tkrueIdBQLdWXdjrmu20= -github.com/openshift/library-go v0.0.0-20221017091500-9aea380195f4/go.mod h1:KPBAXGaq7pPmA+1wUVtKr5Axg3R68IomWDkzaOxIhxM= +github.com/openshift/library-go v0.0.0-20221017195819-7f7c08fa1941 h1:M90EN6nI6hpOuf3oPzwiRoOnIJmc885xqsPaypNdOEU= +github.com/openshift/library-go v0.0.0-20221017195819-7f7c08fa1941/go.mod h1:KPBAXGaq7pPmA+1wUVtKr5Axg3R68IomWDkzaOxIhxM= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -793,6 +792,7 @@ golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= 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= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -932,30 +932,30 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/api v0.18.0-beta.2/go.mod h1:2oeNnWEqcSmaM/ibSh3t7xcIqbkGXhzZdn4ezV9T4m0= -k8s.io/api v0.25.1 h1:yL7du50yc93k17nH/Xe9jujAYrcDkI/i5DL1jPz4E3M= -k8s.io/api v0.25.1/go.mod h1:hh4itDvrWSJsmeUc28rIFNri8MatNAAxJjKcQmhX6TU= +k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0= +k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG55nHd1DCoHj8= k8s.io/apiextensions-apiserver v0.18.0-beta.2/go.mod h1:Hnrg5jx8/PbxRbUoqDGxtQkULjwx8FDW4WYJaKNK+fk= k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.18.0-beta.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/apimachinery v0.25.1 h1:t0XrnmCEHVgJlR2arwO8Awp9ylluDic706WePaYCBTI= -k8s.io/apimachinery v0.25.1/go.mod h1:hqqA1X0bsgsxI6dXsJ4HnNTBOmJNxyPp8dw3u2fSHwA= +k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU= +k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0= k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= k8s.io/apiserver v0.18.0-beta.2/go.mod h1:bnblMkMoCFnIfVnVftd0SXJPzyvrk3RtaqSbblphF/A= k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= k8s.io/client-go v0.18.0-beta.2/go.mod h1:UvuVxHjKWIcgy0iMvF+bwNDW7l0mskTNOaOW1Qv5BMA= -k8s.io/client-go v0.25.1 h1:uFj4AJKtE1/ckcSKz8IhgAuZTdRXZDKev8g387ndD58= -k8s.io/client-go v0.25.1/go.mod h1:rdFWTLV/uj2C74zGbQzOsmXPUtMAjSf7ajil4iJUNKo= +k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E= +k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8= k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= k8s.io/code-generator v0.18.0-beta.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= k8s.io/component-base v0.18.0-beta.2/go.mod h1:HVk5FpRnyzQ/MjBr9//e/yEBjTVa2qjGXCTuUzcD7ks= -k8s.io/component-base v0.25.1 h1:Wmj33QwddVwsJFJWmXlf24Nu8do2bGHLabXHrKz7Org= -k8s.io/component-base v0.25.1/go.mod h1:j78+TFdsKM8RXHfM88oeAdZu2v9qMZdQZOfg0LGW+q4= +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-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/pkg/operator/starter.go b/pkg/operator/starter.go index e73c27a99..5ab5c0bcc 100644 --- a/pkg/operator/starter.go +++ b/pkg/operator/starter.go @@ -1,18 +1,18 @@ package operator import ( + "bytes" "context" "fmt" + "os" "strings" "time" - v1 "github.com/openshift/client-go/config/listers/config/v1" - "github.com/openshift/library-go/pkg/controller/factory" - "github.com/openshift/library-go/pkg/operator/events" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apiextclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" kubeclient "k8s.io/client-go/kubernetes" @@ -23,28 +23,34 @@ import ( opv1 "github.com/openshift/api/operator/v1" configclient "github.com/openshift/client-go/config/clientset/versioned" configinformers "github.com/openshift/client-go/config/informers/externalversions" + v1 "github.com/openshift/client-go/config/listers/config/v1" + "github.com/openshift/library-go/pkg/config/client" "github.com/openshift/library-go/pkg/controller/controllercmd" + "github.com/openshift/library-go/pkg/controller/factory" "github.com/openshift/library-go/pkg/operator/csi/csicontrollerset" "github.com/openshift/library-go/pkg/operator/csi/csidrivercontrollerservicecontroller" "github.com/openshift/library-go/pkg/operator/csi/csidrivernodeservicecontroller" - "github.com/openshift/library-go/pkg/operator/deploymentcontroller" + dc "github.com/openshift/library-go/pkg/operator/deploymentcontroller" + "github.com/openshift/library-go/pkg/operator/events" goc "github.com/openshift/library-go/pkg/operator/genericoperatorclient" + "github.com/openshift/library-go/pkg/operator/resource/resourceapply" "github.com/openshift/library-go/pkg/operator/resourcesynccontroller" + "github.com/openshift/library-go/pkg/operator/staticresourcecontroller" "github.com/openshift/library-go/pkg/operator/v1helpers" "github.com/openshift/aws-ebs-csi-driver-operator/assets" ) const ( - // Operand and operator run in the same namespace defaultNamespace = "openshift-cluster-csi-drivers" operatorName = "aws-ebs-csi-driver-operator" operandName = "aws-ebs-csi-driver" - instanceName = "ebs.csi.aws.com" secretName = "ebs-cloud-credentials" infraConfigName = "cluster" trustedCAConfigMap = "aws-ebs-csi-driver-trusted-ca-bundle" + hypershiftImageEnvName = "HYPERSHIFT_IMAGE" + cloudConfigNamespace = "openshift-config-managed" cloudConfigName = "kube-cloud-config" caBundleKey = "ca-bundle.pem" @@ -52,82 +58,157 @@ const ( infrastructureName = "cluster" ) -func RunOperator(ctx context.Context, controllerConfig *controllercmd.ControllerContext) error { - // Create core clientset and informer - kubeClient := kubeclient.NewForConfigOrDie(rest.AddUserAgent(controllerConfig.KubeConfig, operatorName)) - kubeInformersForNamespaces := v1helpers.NewKubeInformersForNamespaces(kubeClient, defaultNamespace, cloudConfigNamespace, "") - secretInformer := kubeInformersForNamespaces.InformersFor(defaultNamespace).Core().V1().Secrets() - nodeInformer := kubeInformersForNamespaces.InformersFor("").Core().V1().Nodes() - configMapInformer := kubeInformersForNamespaces.InformersFor(defaultNamespace).Core().V1().ConfigMaps() +func RunOperator(ctx context.Context, controllerConfig *controllercmd.ControllerContext, guestKubeConfigString string) error { + // Create core clientset and informer for the MANAGEMENT cluster. + eventRecorder := controllerConfig.EventRecorder + controlPlaneNamespace := controllerConfig.OperatorNamespace + controlPlaneKubeClient := kubeclient.NewForConfigOrDie(rest.AddUserAgent(controllerConfig.KubeConfig, operatorName)) + controlPlaneKubeInformersForNamespaces := v1helpers.NewKubeInformersForNamespaces(controlPlaneKubeClient, controlPlaneNamespace) + controlPlaneSecretInformer := controlPlaneKubeInformersForNamespaces.InformersFor(controlPlaneNamespace).Core().V1().Secrets() + controlPlaneConfigMapInformer := controlPlaneKubeInformersForNamespaces.InformersFor(controlPlaneNamespace).Core().V1().ConfigMaps() + + // Create informer for the ConfigMaps in the operator namespace. + // This is used to get the custom CA bundle to use when accessing the AWS API. + // This is only synced on standalone OCP clusters. + controlPlaneCloudConfigInformers := v1helpers.NewKubeInformersForNamespaces(controlPlaneKubeClient, controlPlaneNamespace, cloudConfigNamespace) + controlPlaneCloudConfigInformer := controlPlaneCloudConfigInformers.InformersFor(controlPlaneNamespace).Core().V1().ConfigMaps() + controlPlaneCloudConfigLister := controlPlaneCloudConfigInformer.Lister().ConfigMaps(controlPlaneNamespace) - apiExtClient, err := apiextclient.NewForConfig(rest.AddUserAgent(controllerConfig.KubeConfig, operatorName)) + controlPlaneDynamicClient, err := dynamic.NewForConfig(controllerConfig.KubeConfig) if err != nil { return err } - // Create config clientset and informer. This is used to get the cluster ID - configClient := configclient.NewForConfigOrDie(rest.AddUserAgent(controllerConfig.KubeConfig, operatorName)) - configInformers := configinformers.NewSharedInformerFactory(configClient, 20*time.Minute) - infraInformer := configInformers.Config().V1().Infrastructures() + // Create core clientset for the GUEST cluster. + guestNamespace := defaultNamespace + guestKubeConfig := controllerConfig.KubeConfig + guestKubeClient := controlPlaneKubeClient + isHypershift := guestKubeConfigString != "" + if isHypershift { + guestKubeConfig, err = client.GetKubeConfigOrInClusterConfig(guestKubeConfigString, nil) + if err != nil { + return err + } + guestKubeClient = kubeclient.NewForConfigOrDie(rest.AddUserAgent(guestKubeConfig, operatorName)) - // Create informer for the ConfigMaps in the openshift-config-managed namespace. This is used to get the custom CA - // bundle to use when accessing the AWS API. - cloudConfigInformer := kubeInformersForNamespaces.InformersFor(cloudConfigNamespace).Core().V1().ConfigMaps() - cloudConfigLister := cloudConfigInformer.Lister().ConfigMaps(cloudConfigNamespace) + // Create all events in the GUEST cluster. + // Use name of the operator Deployment in the management cluster + namespace + // in the guest cluster as the closest approximation of the real involvedObject. + controllerRef, err := events.GetControllerReferenceForCurrentPod(ctx, controlPlaneKubeClient, controlPlaneNamespace, nil) + controllerRef.Namespace = guestNamespace + if err != nil { + klog.Warningf("unable to get owner reference (falling back to namespace): %v", err) + } + eventRecorder = events.NewKubeRecorder(guestKubeClient.CoreV1().Events(guestNamespace), operandName, controllerRef) + } - // Create GenericOperatorclient. This is used by the library-go controllers created down below - gvr := opv1.SchemeGroupVersion.WithResource("clustercsidrivers") - operatorClient, dynamicInformers, err := goc.NewClusterScopedOperatorClientWithConfigName(controllerConfig.KubeConfig, gvr, instanceName) + guestAPIExtClient, err := apiextclient.NewForConfig(rest.AddUserAgent(guestKubeConfig, operatorName)) if err != nil { return err } - dynamicClient, err := dynamic.NewForConfig(controllerConfig.KubeConfig) + guestDynamicClient, err := dynamic.NewForConfig(guestKubeConfig) if err != nil { return err } - csiControllerSet := csicontrollerset.NewCSIControllerSet( - operatorClient, - controllerConfig.EventRecorder, + // Client informers for the GUEST cluster. + guestKubeInformersForNamespaces := v1helpers.NewKubeInformersForNamespaces(guestKubeClient, guestNamespace, "") + guestConfigMapInformer := guestKubeInformersForNamespaces.InformersFor(guestNamespace).Core().V1().ConfigMaps() + guestNodeInformer := guestKubeInformersForNamespaces.InformersFor("").Core().V1().Nodes() + + guestConfigClient := configclient.NewForConfigOrDie(rest.AddUserAgent(guestKubeConfig, operatorName)) + guestConfigInformers := configinformers.NewSharedInformerFactory(guestConfigClient, 20*time.Minute) + guestInfraInformer := guestConfigInformers.Config().V1().Infrastructures() + + // Create client and informers for our ClusterCSIDriver CR. + gvr := opv1.SchemeGroupVersion.WithResource("clustercsidrivers") + guestOperatorClient, guestDynamicInformers, err := goc.NewClusterScopedOperatorClientWithConfigName(guestKubeConfig, gvr, string(opv1.AWSEBSCSIDriver)) + if err != nil { + return err + } + + controlPlaneInformersForEvents := []factory.Informer{ + controlPlaneSecretInformer.Informer(), + controlPlaneConfigMapInformer.Informer(), + guestNodeInformer.Informer(), + guestInfraInformer.Informer(), + } + if !isHypershift { + controlPlaneInformersForEvents = append(controlPlaneInformersForEvents, controlPlaneCloudConfigInformer.Informer()) + } + + // Start controllers that manage resources in the MANAGEMENT cluster. + controlPlaneCSIControllerSet := csicontrollerset.NewCSIControllerSet( + guestOperatorClient, + eventRecorder, ).WithLogLevelController().WithManagementStateController( operandName, false, ).WithStaticResourcesController( - "AWSEBSDriverStaticResourcesController", - kubeClient, - dynamicClient, - kubeInformersForNamespaces, + "AWSEBSDriverControlPlaneStaticResourcesController", + controlPlaneKubeClient, + controlPlaneDynamicClient, + controlPlaneKubeInformersForNamespaces, + assetWithNamespaceFunc(controlPlaneNamespace), + []string{ + "controller_sa.yaml", + "controller_pdb.yaml", + "cabundle_cm.yaml", + }, + ).WithCSIConfigObserverController( + "AWSEBSDriverCSIConfigObserverController", + guestConfigInformers, + ).WithCSIDriverControllerService( + "AWSEBSDriverControllerServiceController", + assets.ReadFile, + "controller.yaml", + controlPlaneKubeClient, + controlPlaneKubeInformersForNamespaces.InformersFor(controlPlaneNamespace), + guestConfigInformers, + controlPlaneInformersForEvents, + withHypershiftDeploymentHook(isHypershift, os.Getenv(hypershiftImageEnvName)), + withHypershiftReplicasHook(isHypershift, guestNodeInformer.Lister()), + withNamespaceDeploymentHook(controlPlaneNamespace), + csidrivercontrollerservicecontroller.WithSecretHashAnnotationHook(controlPlaneNamespace, secretName, controlPlaneSecretInformer), + csidrivercontrollerservicecontroller.WithObservedProxyDeploymentHook(), + withCustomAWSCABundle(isHypershift, controlPlaneCloudConfigLister), + withAWSRegion(guestInfraInformer.Lister()), + withCustomTags(guestInfraInformer.Lister()), + withCustomEndPoint(guestInfraInformer.Lister()), + csidrivercontrollerservicecontroller.WithCABundleDeploymentHook( + controlPlaneNamespace, + trustedCAConfigMap, + controlPlaneConfigMapInformer, + ), + ) + if err != nil { + return err + } + + // Start controllers that manage resources in GUEST clusters. + guestCSIControllerSet := csicontrollerset.NewCSIControllerSet( + guestOperatorClient, + eventRecorder, + ).WithStaticResourcesController( + "AWSEBSDriverGuestStaticResourcesController", + guestKubeClient, + guestDynamicClient, + guestKubeInformersForNamespaces, assets.ReadFile, []string{ "storageclass_gp2.yaml", + "volumesnapshotclass.yaml", "csidriver.yaml", - "controller_sa.yaml", - "controller_pdb.yaml", "node_sa.yaml", - "service.yaml", - "cabundle_cm.yaml", - "rbac/attacher_role.yaml", - "rbac/attacher_binding.yaml", "rbac/privileged_role.yaml", - "rbac/controller_privileged_binding.yaml", "rbac/node_privileged_binding.yaml", - "rbac/provisioner_role.yaml", - "rbac/provisioner_binding.yaml", - "rbac/resizer_role.yaml", - "rbac/resizer_binding.yaml", - "rbac/snapshotter_role.yaml", - "rbac/snapshotter_binding.yaml", - "rbac/prometheus_role.yaml", - "rbac/prometheus_rolebinding.yaml", - "rbac/kube_rbac_proxy_role.yaml", - "rbac/kube_rbac_proxy_binding.yaml", }, ).WithConditionalStaticResourcesController( "AWSEBSDriverConditionalStaticResourcesController", - kubeClient, - dynamicClient, - kubeInformersForNamespaces, + guestKubeClient, + guestDynamicClient, + guestKubeInformersForNamespaces, assets.ReadFile, []string{ "volumesnapshotclass.yaml", @@ -135,114 +216,128 @@ func RunOperator(ctx context.Context, controllerConfig *controllercmd.Controller // Only install when CRD exists. func() bool { name := "volumesnapshotclasses.snapshot.storage.k8s.io" - _, err := apiExtClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), name, metav1.GetOptions{}) + _, err := guestAPIExtClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), name, metav1.GetOptions{}) return err == nil }, // Don't ever remove. func() bool { return false }, - ).WithCSIConfigObserverController( - "AWSEBSDriverCSIConfigObserverController", - configInformers, - ).WithCSIDriverControllerService( - "AWSEBSDriverControllerServiceController", - assets.ReadFile, - "controller.yaml", - kubeClient, - kubeInformersForNamespaces.InformersFor(defaultNamespace), - configInformers, - []factory.Informer{ - secretInformer.Informer(), - nodeInformer.Informer(), - cloudConfigInformer.Informer(), - infraInformer.Informer(), - configMapInformer.Informer(), - }, - csidrivercontrollerservicecontroller.WithSecretHashAnnotationHook(defaultNamespace, secretName, secretInformer), - csidrivercontrollerservicecontroller.WithObservedProxyDeploymentHook(), - csidrivercontrollerservicecontroller.WithReplicasHook(nodeInformer.Lister()), - withCustomCABundle(cloudConfigLister), - withCustomTags(infraInformer.Lister()), - withCustomEndPoint(infraInformer.Lister()), - csidrivercontrollerservicecontroller.WithCABundleDeploymentHook( - defaultNamespace, - trustedCAConfigMap, - configMapInformer, - ), ).WithCSIDriverNodeService( "AWSEBSDriverNodeServiceController", assets.ReadFile, "node.yaml", - kubeClient, - kubeInformersForNamespaces.InformersFor(defaultNamespace), - []factory.Informer{configMapInformer.Informer()}, + guestKubeClient, + guestKubeInformersForNamespaces.InformersFor(guestNamespace), + []factory.Informer{guestConfigMapInformer.Informer()}, csidrivernodeservicecontroller.WithObservedProxyDaemonSetHook(), csidrivernodeservicecontroller.WithCABundleDaemonSetHook( - defaultNamespace, + guestNamespace, trustedCAConfigMap, - configMapInformer, + guestConfigMapInformer, ), - ).WithServiceMonitorController( - "AWSEBSDriverServiceMonitorController", - dynamicClient, - assets.ReadFile, - "servicemonitor.yaml", ).WithStorageClassController( "AWSEBSDriverStorageClassController", assets.ReadFile, "storageclass_gp3.yaml", - kubeClient, - kubeInformersForNamespaces.InformersFor(""), + guestKubeClient, + guestKubeInformersForNamespaces.InformersFor(""), ) - if err != nil { - return err - } - caSyncController, err := newCustomCABundleSyncer( - operatorClient, - kubeInformersForNamespaces, - kubeClient, - controllerConfig.EventRecorder, - ) - if err != nil { - return fmt.Errorf("could not create the custom CA bundle syncer: %w", err) + if !isHypershift { + caSyncController, err := newCustomAWSBundleSyncer( + guestOperatorClient, + controlPlaneCloudConfigInformers, + controlPlaneKubeClient, + controlPlaneNamespace, + eventRecorder, + ) + if err != nil { + return fmt.Errorf("could not create the custom CA bundle syncer: %w", err) + } + + klog.Info("Starting custom CA bundle informers") + go controlPlaneCloudConfigInformers.Start(ctx.Done()) + + klog.Info("Starting custom CA bundle sync controller") + go caSyncController.Run(ctx, 1) + + staticResourcesController := staticresourcecontroller.NewStaticResourceController( + "AWSEBSDriverStaticResourcesController", + assets.ReadFile, + []string{ + "rbac/attacher_role.yaml", + "rbac/attacher_binding.yaml", + "rbac/provisioner_role.yaml", + "rbac/provisioner_binding.yaml", + "rbac/resizer_role.yaml", + "rbac/resizer_binding.yaml", + "rbac/snapshotter_role.yaml", + "rbac/snapshotter_binding.yaml", + "service.yaml", + "rbac/prometheus_role.yaml", + "rbac/prometheus_rolebinding.yaml", + "rbac/kube_rbac_proxy_role.yaml", + "rbac/kube_rbac_proxy_binding.yaml", + }, + (&resourceapply.ClientHolder{}).WithKubernetes(controlPlaneKubeClient).WithDynamicClient(controlPlaneDynamicClient), + guestOperatorClient, + eventRecorder, + ).AddKubeInformers(controlPlaneKubeInformersForNamespaces) + + klog.Info("Starting static resources controller") + go staticResourcesController.Run(ctx, 1) + + serviceMonitorController := staticresourcecontroller.NewStaticResourceController( + "AWSEBSDriverServiceMonitorController", + assets.ReadFile, + []string{"servicemonitor.yaml"}, + (&resourceapply.ClientHolder{}).WithDynamicClient(controlPlaneDynamicClient), + guestOperatorClient, + eventRecorder, + ).WithIgnoreNotFoundOnCreate() + + klog.Info("Starting ServiceMonitor controller") + go serviceMonitorController.Run(ctx, 1) } - klog.Info("Starting the informers") - go kubeInformersForNamespaces.Start(ctx.Done()) - go dynamicInformers.Start(ctx.Done()) - go configInformers.Start(ctx.Done()) + klog.Info("Starting the control plane informers") + go controlPlaneKubeInformersForNamespaces.Start(ctx.Done()) + + klog.Info("Starting control plane controllerset") + go controlPlaneCSIControllerSet.Run(ctx, 1) - klog.Info("Starting controllerset") - go csiControllerSet.Run(ctx, 1) - go caSyncController.Run(ctx, 1) + klog.Info("Starting the guest cluster informers") + go guestKubeInformersForNamespaces.Start(ctx.Done()) + go guestDynamicInformers.Start(ctx.Done()) + go guestConfigInformers.Start(ctx.Done()) + + klog.Info("Starting guest cluster controllerset") + go guestCSIControllerSet.Run(ctx, 1) <-ctx.Done() return fmt.Errorf("stopped") } -type controllerTemplateData struct { - CABundleConfigMap string -} - -// withCustomCABundle executes the asset as a template to fill out the parts required when using a custom CA bundle. +// withCustomAWSCABundle executes the asset as a template to fill out the parts required when using a custom CA bundle. // The `caBundleConfigMap` parameter specifies the name of the ConfigMap containing the custom CA bundle. If the // argument supplied is empty, then no custom CA bundle will be used. -func withCustomCABundle(cloudConfigLister corev1listers.ConfigMapNamespaceLister) deploymentcontroller.DeploymentHookFunc { +func withCustomAWSCABundle(isHypershift bool, cloudConfigLister corev1listers.ConfigMapNamespaceLister) dc.DeploymentHookFunc { return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { - switch used, err := isCustomCABundleUsed(cloudConfigLister); { - case err != nil: + configName, err := customAWSCABundle(isHypershift, cloudConfigLister) + if err != nil { return fmt.Errorf("could not determine if a custom CA bundle is in use: %w", err) - case !used: + } + if configName == "" { return nil } + deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, corev1.Volume{ Name: "ca-bundle", VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: cloudConfigName}, + LocalObjectReference: corev1.LocalObjectReference{Name: configName}, }, }, }) @@ -266,7 +361,7 @@ func withCustomCABundle(cloudConfigLister corev1listers.ConfigMapNamespaceLister } } -func withCustomEndPoint(infraLister v1.InfrastructureLister) deploymentcontroller.DeploymentHookFunc { +func withCustomEndPoint(infraLister v1.InfrastructureLister) dc.DeploymentHookFunc { return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { infra, err := infraLister.Get(infrastructureName) if err != nil { @@ -301,10 +396,11 @@ func withCustomEndPoint(infraLister v1.InfrastructureLister) deploymentcontrolle } } -func newCustomCABundleSyncer( +func newCustomAWSBundleSyncer( operatorClient v1helpers.OperatorClient, kubeInformers v1helpers.KubeInformersForNamespaces, kubeClient kubeclient.Interface, + destinationNamespace string, eventRecorder events.Recorder, ) (factory.Controller, error) { // sync config map with additional trust bundle to the operator namespace, @@ -314,7 +410,7 @@ func newCustomCABundleSyncer( Name: cloudConfigName, } dstConfigMap := resourcesynccontroller.ResourceLocation{ - Namespace: defaultNamespace, + Namespace: destinationNamespace, Name: cloudConfigName, } certController := resourcesynccontroller.NewResourceSyncController( @@ -330,23 +426,30 @@ func newCustomCABundleSyncer( return certController, nil } -// isCustomCABundleUsed returns true if the cloud config ConfigMap exists and contains a custom CA bundle. -func isCustomCABundleUsed(cloudConfigLister corev1listers.ConfigMapNamespaceLister) (bool, error) { - cloudConfigCM, err := cloudConfigLister.Get(cloudConfigName) - if errors.IsNotFound(err) { - // no cloud config ConfigMap so there is no CA bundle - return false, nil +// customAWSCABundle returns true if the cloud config ConfigMap exists and contains a custom CA bundle. +func customAWSCABundle(isHypershift bool, cloudConfigLister corev1listers.ConfigMapNamespaceLister) (string, error) { + configName := cloudConfigName + if isHypershift { + configName = "user-ca-bundle" + } + + cloudConfigCM, err := cloudConfigLister.Get(configName) + if apierrors.IsNotFound(err) { + return "", nil } if err != nil { - return false, fmt.Errorf("failed to get the %s/%s ConfigMap: %w", cloudConfigNamespace, cloudConfigName, err) + return "", fmt.Errorf("failed to get the %s ConfigMap: %w", configName, err) + } + + if _, ok := cloudConfigCM.Data[caBundleKey]; !ok { + return "", nil } - _, exists := cloudConfigCM.Data[caBundleKey] - return exists, nil + return configName, nil } // withCustomTags add tags from Infrastructure.Status.PlatformStatus.AWS.ResourceTags to the driver command line as // --extra-tags==,=,... -func withCustomTags(infraLister v1.InfrastructureLister) deploymentcontroller.DeploymentHookFunc { +func withCustomTags(infraLister v1.InfrastructureLister) dc.DeploymentHookFunc { return func(spec *opv1.OperatorSpec, deployment *appsv1.Deployment) error { infra, err := infraLister.Get(infrastructureName) if err != nil { @@ -379,3 +482,176 @@ func withCustomTags(infraLister v1.InfrastructureLister) deploymentcontroller.De return nil } } + +func assetWithNamespaceFunc(namespace string) resourceapply.AssetFunc { + return func(name string) ([]byte, error) { + content, err := assets.ReadFile(name) + if err != nil { + panic(err) + } + return bytes.ReplaceAll(content, []byte("${NAMESPACE}"), []byte(namespace)), nil + } +} + +func withNamespaceDeploymentHook(namespace string) dc.DeploymentHookFunc { + return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { + deployment.Namespace = namespace + return nil + } +} + +func withHypershiftReplicasHook(isHypershift bool, guestNodeLister corev1listers.NodeLister) dc.DeploymentHookFunc { + if !isHypershift { + return csidrivercontrollerservicecontroller.WithReplicasHook(guestNodeLister) + } + return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { + // TODO: get this information from HostedControlPlane.Spec.AvailabilityPolicy + replicas := int32(1) + deployment.Spec.Replicas = &replicas + return nil + } + +} + +func withHypershiftDeploymentHook(isHypershift bool, hypershiftImage string) dc.DeploymentHookFunc { + return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { + if !isHypershift { + return nil + } + + // Inject into the pod the volumes used by CSI and token minter sidecars. + podSpec := &deployment.Spec.Template.Spec + podSpec.Volumes = append(podSpec.Volumes, + corev1.Volume{ + Name: "hosted-kubeconfig", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + // FIXME: use a ServiceAccount from the guest cluster + SecretName: "admin-kubeconfig", + }, + }, + }, + ) + + // The bound-sa-token volume must be a empty disk in Hypershift. + for i := range podSpec.Volumes { + if podSpec.Volumes[i].Name != "bound-sa-token" { + continue + } + podSpec.Volumes[i].VolumeSource = corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: corev1.StorageMediumMemory, + }, + } + } + + // The metrics-serving-cert volume is not used in Hypershift. + for i := range podSpec.Volumes { + if podSpec.Volumes[i].Name == "metrics-serving-cert" { + podSpec.Volumes = append(podSpec.Volumes[:i], podSpec.Volumes[i+1:]...) + break + } + } + + filtered := []corev1.Container{} + for i := range podSpec.Containers { + switch podSpec.Containers[i].Name { + case "driver-kube-rbac-proxy": + case "provisioner-kube-rbac-proxy": + case "attacher-kube-rbac-proxy": + case "resizer-kube-rbac-proxy": + case "snapshotter-kube-rbac-proxy": + default: + filtered = append(filtered, podSpec.Containers[i]) + } + } + podSpec.Containers = filtered + + // Inject into the CSI sidecars the hosted Kubeconfig. + for i := range podSpec.Containers { + container := &podSpec.Containers[i] + switch container.Name { + case "csi-provisioner": + case "csi-attacher": + case "csi-snapshotter": + case "csi-resizer": + default: + continue + } + container.Args = append(container.Args, "--kubeconfig=$(KUBECONFIG)") + container.Env = append(container.Env, corev1.EnvVar{ + Name: "KUBECONFIG", + Value: "/etc/hosted-kubernetes/kubeconfig", + }) + container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{ + Name: "hosted-kubeconfig", + MountPath: "/etc/hosted-kubernetes", + ReadOnly: true, + }) + } + + // Add the token minter sidecar into the pod. + podSpec.Containers = append(podSpec.Containers, corev1.Container{ + Name: "token-minter", + Image: hypershiftImage, + ImagePullPolicy: corev1.PullIfNotPresent, + Command: []string{"/usr/bin/control-plane-operator", "token-minter"}, + Args: []string{ + "--service-account-namespace=openshift-cluster-csi-drivers", + "--service-account-name=aws-ebs-csi-driver-controller-sa", + "--token-audience=openshift", + "--token-file=/var/run/secrets/openshift/serviceaccount/token", + "--kubeconfig=/etc/hosted-kubernetes/kubeconfig", + }, + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("10m"), + corev1.ResourceMemory: resource.MustParse("10Mi"), + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "bound-sa-token", + MountPath: "/var/run/secrets/openshift/serviceaccount", + }, + { + Name: "hosted-kubeconfig", + MountPath: "/etc/hosted-kubernetes", + ReadOnly: true, + }, + }, + }) + + return nil + } +} + +func withAWSRegion(infraLister v1.InfrastructureLister) dc.DeploymentHookFunc { + return func(_ *opv1.OperatorSpec, deployment *appsv1.Deployment) error { + infra, err := infraLister.Get(infrastructureName) + if err != nil { + return err + } + + if infra.Status.PlatformStatus == nil || infra.Status.PlatformStatus.AWS == nil { + return nil + } + + region := infra.Status.PlatformStatus.AWS.Region + if region == "" { + return nil + } + + for i := range deployment.Spec.Template.Spec.Containers { + container := &deployment.Spec.Template.Spec.Containers[i] + if container.Name != "csi-driver" { + continue + } + container.Env = append(container.Env, corev1.EnvVar{ + Name: "AWS_REGION", + Value: region, + }) + } + return nil + } +} diff --git a/pkg/operator/starter_test.go b/pkg/operator/starter_test.go index d084f9668..3fbd4cfc5 100644 --- a/pkg/operator/starter_test.go +++ b/pkg/operator/starter_test.go @@ -152,7 +152,7 @@ func TestWithCustomCABundle(t *testing.T) { return cloudConfigInformer.Informer().HasSynced(), nil }) deployment := tc.inDeployment.DeepCopy() - err := withCustomCABundle(cloudConfigLister)(nil, deployment) + err := withCustomAWSCABundle(false, cloudConfigLister)(nil, deployment) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go index fd2b3a42b..86d0903b8 100644 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/vendor/github.com/google/go-cmp/cmp/compare.go @@ -36,12 +36,11 @@ import ( "strings" "github.com/google/go-cmp/cmp/internal/diff" + "github.com/google/go-cmp/cmp/internal/flags" "github.com/google/go-cmp/cmp/internal/function" "github.com/google/go-cmp/cmp/internal/value" ) -// TODO(≥go1.18): Use any instead of interface{}. - // Equal reports whether x and y are equal by recursively applying the // following rules in the given order to x and y and all of their sub-values: // @@ -320,6 +319,7 @@ func (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool { } func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value { + v = sanitizeValue(v, f.Type().In(0)) if !s.dynChecker.Next() { return f.Call([]reflect.Value{v})[0] } @@ -343,6 +343,8 @@ func (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value { } func (s *state) callTTBFunc(f, x, y reflect.Value) bool { + x = sanitizeValue(x, f.Type().In(0)) + y = sanitizeValue(y, f.Type().In(1)) if !s.dynChecker.Next() { return f.Call([]reflect.Value{x, y})[0].Bool() } @@ -370,6 +372,19 @@ func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { ret = f.Call(vs)[0] } +// sanitizeValue converts nil interfaces of type T to those of type R, +// assuming that T is assignable to R. +// Otherwise, it returns the input value as is. +func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { + // TODO(≥go1.10): Workaround for reflect bug (https://golang.org/issue/22143). + if !flags.AtLeastGo110 { + if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { + return reflect.New(t).Elem() + } + } + return v +} + func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) { var addr bool var vax, vay reflect.Value // Addressable versions of vx and vy diff --git a/vendor/github.com/google/go-cmp/cmp/export_panic.go b/vendor/github.com/google/go-cmp/cmp/export_panic.go index ae851fe53..5ff0b4218 100644 --- a/vendor/github.com/google/go-cmp/cmp/export_panic.go +++ b/vendor/github.com/google/go-cmp/cmp/export_panic.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build purego // +build purego package cmp diff --git a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go index e2c0f74e8..21eb54858 100644 --- a/vendor/github.com/google/go-cmp/cmp/export_unsafe.go +++ b/vendor/github.com/google/go-cmp/cmp/export_unsafe.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !purego // +build !purego package cmp diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go index 36062a604..1daaaacc5 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !cmp_debug // +build !cmp_debug package diff diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go index a3b97a1ad..4b91dbcac 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build cmp_debug // +build cmp_debug package diff diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go new file mode 100644 index 000000000..82d1d7fbf --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_legacy.go @@ -0,0 +1,10 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.10 + +package flags + +// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10. +const AtLeastGo110 = false diff --git a/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go new file mode 100644 index 000000000..8646f0529 --- /dev/null +++ b/vendor/github.com/google/go-cmp/cmp/internal/flags/toolchain_recent.go @@ -0,0 +1,10 @@ +// Copyright 2019, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.10 + +package flags + +// AtLeastGo110 reports whether the Go toolchain is at least Go 1.10. +const AtLeastGo110 = true diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go b/vendor/github.com/google/go-cmp/cmp/internal/value/name.go index 7b498bb2c..b6c12cefb 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/name.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/name.go @@ -9,8 +9,6 @@ import ( "strconv" ) -var anyType = reflect.TypeOf((*interface{})(nil)).Elem() - // TypeString is nearly identical to reflect.Type.String, // but has an additional option to specify that full type names be used. func TypeString(t reflect.Type, qualified bool) string { @@ -22,11 +20,6 @@ func appendTypeName(b []byte, t reflect.Type, qualified, elideFunc bool) []byte // of the same name and within the same package, // but declared within the namespace of different functions. - // Use the "any" alias instead of "interface{}" for better readability. - if t == anyType { - return append(b, "any"...) - } - // Named type. if t.Name() != "" { if qualified && t.PkgPath() != "" { diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go index 1a71bfcbd..44f4a5afd 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_purego.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build purego // +build purego package value diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go index 16e6860af..a605953d4 100644 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go +++ b/vendor/github.com/google/go-cmp/cmp/internal/value/pointer_unsafe.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !purego // +build !purego package value diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go index c71003463..f01eff318 100644 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ b/vendor/github.com/google/go-cmp/cmp/path.go @@ -178,7 +178,7 @@ type structField struct { unexported bool mayForce bool // Forcibly allow visibility paddr bool // Was parent addressable? - pvx, pvy reflect.Value // Parent values (always addressable) + pvx, pvy reflect.Value // Parent values (always addressible) field reflect.StructField // Field information } diff --git a/vendor/github.com/google/go-cmp/cmp/report_compare.go b/vendor/github.com/google/go-cmp/cmp/report_compare.go index 1ef65ac1d..104bb3053 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_compare.go +++ b/vendor/github.com/google/go-cmp/cmp/report_compare.go @@ -116,10 +116,7 @@ func (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out } // For leaf nodes, format the value based on the reflect.Values alone. - // As a special case, treat equal []byte as a leaf nodes. - isBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == reflect.TypeOf(byte(0)) - isEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0 - if v.MaxDepth == 0 || isEqualBytes { + if v.MaxDepth == 0 { switch opts.DiffMode { case diffUnknown, diffIdentical: // Format Equal. diff --git a/vendor/github.com/google/go-cmp/cmp/report_reflect.go b/vendor/github.com/google/go-cmp/cmp/report_reflect.go index 287b89358..33f03577f 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_reflect.go +++ b/vendor/github.com/google/go-cmp/cmp/report_reflect.go @@ -207,11 +207,10 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, // Check whether this is a []byte of text data. if t.Elem() == reflect.TypeOf(byte(0)) { b := v.Bytes() - isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) } + isPrintSpace := func(r rune) bool { return unicode.IsPrint(r) && unicode.IsSpace(r) } if len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 { out = opts.formatString("", string(b)) - skipType = true - return opts.FormatType(t, out) + return opts.WithTypeMode(emitType).FormatType(t, out) } } @@ -282,12 +281,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } defer ptrs.Pop() - // Skip the name only if this is an unnamed pointer type. - // Otherwise taking the address of a value does not reproduce - // the named pointer type. - if v.Type().Name() == "" { - skipType = true // Let the underlying value print the type instead - } + skipType = true // Let the underlying value print the type instead out = opts.FormatValue(v.Elem(), t.Kind(), ptrs) out = wrapTrunkReference(ptrRef, opts.PrintAddresses, out) out = &textWrap{Prefix: "&", Value: out} @@ -298,6 +292,7 @@ func (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, } // Interfaces accept different concrete types, // so configure the underlying value to explicitly print the type. + skipType = true // Print the concrete type instead return opts.WithTypeMode(emitType).FormatValue(v.Elem(), t.Kind(), ptrs) default: panic(fmt.Sprintf("%v kind not handled", v.Kind())) diff --git a/vendor/github.com/google/go-cmp/cmp/report_slices.go b/vendor/github.com/google/go-cmp/cmp/report_slices.go index 68b5c1ae1..2ad3bc85b 100644 --- a/vendor/github.com/google/go-cmp/cmp/report_slices.go +++ b/vendor/github.com/google/go-cmp/cmp/report_slices.go @@ -80,7 +80,7 @@ func (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool { } // Use specialized string diffing for longer slices or strings. - const minLength = 32 + const minLength = 64 return vx.Len() >= minLength && vy.Len() >= minLength } @@ -563,10 +563,10 @@ func cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []d nx := ds.NumIdentical + ds.NumRemoved + ds.NumModified ny := ds.NumIdentical + ds.NumInserted + ds.NumModified var numLeadingIdentical, numTrailingIdentical int - for j := 0; j < nx && j < ny && eq(ix+j, iy+j); j++ { + for i := 0; i < nx && i < ny && eq(ix+i, iy+i); i++ { numLeadingIdentical++ } - for j := 0; j < nx && j < ny && eq(ix+nx-1-j, iy+ny-1-j); j++ { + for i := 0; i < nx && i < ny && eq(ix+nx-1-i, iy+ny-1-i); i++ { numTrailingIdentical++ } if numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 { diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go index 73876f688..d37dfbf73 100644 --- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go +++ b/vendor/k8s.io/client-go/plugin/pkg/client/auth/exec/exec.go @@ -199,18 +199,14 @@ func newAuthenticator(c *cache, isTerminalFunc func(int) bool, config *api.ExecC now: time.Now, environ: os.Environ, - connTracker: connTracker, + defaultDialer: defaultDialer, + connTracker: connTracker, } for _, env := range config.Env { a.env = append(a.env, env.Name+"="+env.Value) } - // these functions are made comparable and stored in the cache so that repeated clientset - // construction with the same rest.Config results in a single TLS cache and Authenticator - a.getCert = &transport.GetCertHolder{GetCert: a.cert} - a.dial = &transport.DialHolder{Dial: defaultDialer.DialContext} - return c.put(key, a), nil } @@ -265,6 +261,8 @@ type Authenticator struct { now func() time.Time environ func() []string + // defaultDialer is used for clients which don't specify a custom dialer + defaultDialer *connrotation.Dialer // connTracker tracks all connections opened that we need to close when rotating a client certificate connTracker *connrotation.ConnectionTracker @@ -275,12 +273,6 @@ type Authenticator struct { mu sync.Mutex cachedCreds *credentials exp time.Time - - // getCert makes Authenticator.cert comparable to support TLS config caching - getCert *transport.GetCertHolder - // dial is used for clients which do not specify a custom dialer - // it is comparable to support TLS config caching - dial *transport.DialHolder } type credentials struct { @@ -308,20 +300,18 @@ func (a *Authenticator) UpdateTransportConfig(c *transport.Config) error { if c.HasCertCallback() { return errors.New("can't add TLS certificate callback: transport.Config.TLS.GetCert already set") } - c.TLS.GetCert = a.getCert.GetCert - c.TLS.GetCertHolder = a.getCert // comparable for TLS config caching + c.TLS.GetCert = a.cert + var d *connrotation.Dialer if c.Dial != nil { // if c has a custom dialer, we have to wrap it - // TLS config caching is not supported for this config - d := connrotation.NewDialerWithTracker(c.Dial, a.connTracker) - c.Dial = d.DialContext - c.DialHolder = nil + d = connrotation.NewDialerWithTracker(c.Dial, a.connTracker) } else { - c.Dial = a.dial.Dial - c.DialHolder = a.dial // comparable for TLS config caching + d = a.defaultDialer } + c.Dial = d.DialContext + return nil } diff --git a/vendor/k8s.io/client-go/rest/request.go b/vendor/k8s.io/client-go/rest/request.go index acf311361..dba933f7d 100644 --- a/vendor/k8s.io/client-go/rest/request.go +++ b/vendor/k8s.io/client-go/rest/request.go @@ -508,87 +508,6 @@ func (r *Request) URL() *url.URL { return finalURL } -// finalURLTemplate is similar to URL(), but will make all specific parameter values equal -// - instead of name or namespace, "{name}" and "{namespace}" will be used, and all query -// parameters will be reset. This creates a copy of the url so as not to change the -// underlying object. -func (r Request) finalURLTemplate() url.URL { - newParams := url.Values{} - v := []string{"{value}"} - for k := range r.params { - newParams[k] = v - } - r.params = newParams - u := r.URL() - if u == nil { - return url.URL{} - } - - segments := strings.Split(u.Path, "/") - groupIndex := 0 - index := 0 - trimmedBasePath := "" - if r.c.base != nil && strings.Contains(u.Path, r.c.base.Path) { - p := strings.TrimPrefix(u.Path, r.c.base.Path) - if !strings.HasPrefix(p, "/") { - p = "/" + p - } - // store the base path that we have trimmed so we can append it - // before returning the URL - trimmedBasePath = r.c.base.Path - segments = strings.Split(p, "/") - groupIndex = 1 - } - if len(segments) <= 2 { - return *u - } - - const CoreGroupPrefix = "api" - const NamedGroupPrefix = "apis" - isCoreGroup := segments[groupIndex] == CoreGroupPrefix - isNamedGroup := segments[groupIndex] == NamedGroupPrefix - if isCoreGroup { - // checking the case of core group with /api/v1/... format - index = groupIndex + 2 - } else if isNamedGroup { - // checking the case of named group with /apis/apps/v1/... format - index = groupIndex + 3 - } else { - // this should not happen that the only two possibilities are /api... and /apis..., just want to put an - // outlet here in case more API groups are added in future if ever possible: - // https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups - // if a wrong API groups name is encountered, return the {prefix} for url.Path - u.Path = "/{prefix}" - u.RawQuery = "" - return *u - } - // switch segLength := len(segments) - index; segLength { - switch { - // case len(segments) - index == 1: - // resource (with no name) do nothing - case len(segments)-index == 2: - // /$RESOURCE/$NAME: replace $NAME with {name} - segments[index+1] = "{name}" - case len(segments)-index == 3: - if segments[index+2] == "finalize" || segments[index+2] == "status" { - // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name} - segments[index+1] = "{name}" - } else { - // /namespace/$NAMESPACE/$RESOURCE: replace $NAMESPACE with {namespace} - segments[index+1] = "{namespace}" - } - case len(segments)-index >= 4: - segments[index+1] = "{namespace}" - // /namespace/$NAMESPACE/$RESOURCE/$NAME: replace $NAMESPACE with {namespace}, $NAME with {name} - if segments[index+3] != "finalize" && segments[index+3] != "status" { - // /$RESOURCE/$NAME/$SUBRESOURCE: replace $NAME with {name} - segments[index+3] = "{name}" - } - } - u.Path = path.Join(trimmedBasePath, path.Join(segments...)) - return *u -} - func (r *Request) tryThrottleWithInfo(ctx context.Context, retryInfo string) error { if r.rateLimiter == nil { return nil @@ -618,7 +537,7 @@ func (r *Request) tryThrottleWithInfo(ctx context.Context, retryInfo string) err // but we use a throttled logger to prevent spamming. globalThrottledLogger.Infof("%s", message) } - metrics.RateLimiterLatency.Observe(ctx, r.verb, r.finalURLTemplate(), latency) + metrics.RateLimiterLatency.Observe(ctx, r.verb, *r.URL(), latency) return err } @@ -907,7 +826,7 @@ func (r *Request) request(ctx context.Context, fn func(*http.Request, *http.Resp // Metrics for total request latency start := time.Now() defer func() { - metrics.RequestLatency.Observe(ctx, r.verb, r.finalURLTemplate(), time.Since(start)) + metrics.RequestLatency.Observe(ctx, r.verb, *r.URL(), time.Since(start)) }() if r.err != nil { diff --git a/vendor/k8s.io/client-go/transport/cache.go b/vendor/k8s.io/client-go/transport/cache.go index b4f8dab0c..214f0a79c 100644 --- a/vendor/k8s.io/client-go/transport/cache.go +++ b/vendor/k8s.io/client-go/transport/cache.go @@ -17,7 +17,6 @@ limitations under the License. package transport import ( - "context" "fmt" "net" "net/http" @@ -56,9 +55,6 @@ type tlsCacheKey struct { serverName string nextProtos string disableCompression bool - // these functions are wrapped to allow them to be used as map keys - getCert *GetCertHolder - dial *DialHolder } func (t tlsCacheKey) String() string { @@ -66,8 +62,7 @@ func (t tlsCacheKey) String() string { if len(t.keyData) > 0 { keyText = "" } - return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, serverName:%s, disableCompression:%t, getCert:%p, dial:%p", - t.insecure, t.caData, t.certData, keyText, t.serverName, t.disableCompression, t.getCert, t.dial) + return fmt.Sprintf("insecure:%v, caData:%#v, certData:%#v, keyData:%s, serverName:%s, disableCompression:%t", t.insecure, t.caData, t.certData, keyText, t.serverName, t.disableCompression) } func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { @@ -97,10 +92,8 @@ func (c *tlsTransportCache) get(config *Config) (http.RoundTripper, error) { return http.DefaultTransport, nil } - var dial func(ctx context.Context, network, address string) (net.Conn, error) - if config.Dial != nil { - dial = config.Dial - } else { + dial := config.Dial + if dial == nil { dial = (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, @@ -145,18 +138,10 @@ func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) { return tlsCacheKey{}, false, err } - if c.Proxy != nil { + if c.TLS.GetCert != nil || c.Dial != nil || c.Proxy != nil { // cannot determine equality for functions return tlsCacheKey{}, false, nil } - if c.Dial != nil && c.DialHolder == nil { - // cannot determine equality for dial function that doesn't have non-nil DialHolder set as well - return tlsCacheKey{}, false, nil - } - if c.TLS.GetCert != nil && c.TLS.GetCertHolder == nil { - // cannot determine equality for getCert function that doesn't have non-nil GetCertHolder set as well - return tlsCacheKey{}, false, nil - } k := tlsCacheKey{ insecure: c.TLS.Insecure, @@ -164,8 +149,6 @@ func tlsConfigKey(c *Config) (tlsCacheKey, bool, error) { serverName: c.TLS.ServerName, nextProtos: strings.Join(c.TLS.NextProtos, ","), disableCompression: c.DisableCompression, - getCert: c.TLS.GetCertHolder, - dial: c.DialHolder, } if c.TLS.ReloadTLSFiles { diff --git a/vendor/k8s.io/client-go/transport/config.go b/vendor/k8s.io/client-go/transport/config.go index fd853c0b3..89de798f6 100644 --- a/vendor/k8s.io/client-go/transport/config.go +++ b/vendor/k8s.io/client-go/transport/config.go @@ -68,11 +68,7 @@ type Config struct { WrapTransport WrapperFunc // Dial specifies the dial function for creating unencrypted TCP connections. - // If specified, this transport will be non-cacheable unless DialHolder is also set. Dial func(ctx context.Context, network, address string) (net.Conn, error) - // DialHolder can be populated to make transport configs cacheable. - // If specified, DialHolder.Dial must be equal to Dial. - DialHolder *DialHolder // Proxy is the proxy func to be used for all requests made by this // transport. If Proxy is nil, http.ProxyFromEnvironment is used. If Proxy @@ -82,11 +78,6 @@ type Config struct { Proxy func(*http.Request) (*url.URL, error) } -// DialHolder is used to make the wrapped function comparable so that it can be used as a map key. -type DialHolder struct { - Dial func(ctx context.Context, network, address string) (net.Conn, error) -} - // ImpersonationConfig has all the available impersonation options type ImpersonationConfig struct { // UserName matches user.Info.GetName() @@ -152,15 +143,5 @@ type TLSConfig struct { // To use only http/1.1, set to ["http/1.1"]. NextProtos []string - // Callback that returns a TLS client certificate. CertData, CertFile, KeyData and KeyFile supercede this field. - // If specified, this transport is non-cacheable unless CertHolder is populated. - GetCert func() (*tls.Certificate, error) - // CertHolder can be populated to make transport configs that set GetCert cacheable. - // If set, CertHolder.GetCert must be equal to GetCert. - GetCertHolder *GetCertHolder -} - -// GetCertHolder is used to make the wrapped function comparable so that it can be used as a map key. -type GetCertHolder struct { - GetCert func() (*tls.Certificate, error) + GetCert func() (*tls.Certificate, error) // Callback that returns a TLS client certificate. CertData, CertFile, KeyData and KeyFile supercede this field. } diff --git a/vendor/k8s.io/client-go/transport/transport.go b/vendor/k8s.io/client-go/transport/transport.go index eabfce72d..b4a7bfa67 100644 --- a/vendor/k8s.io/client-go/transport/transport.go +++ b/vendor/k8s.io/client-go/transport/transport.go @@ -24,7 +24,6 @@ import ( "fmt" "io/ioutil" "net/http" - "reflect" "sync" "time" @@ -40,10 +39,6 @@ func New(config *Config) (http.RoundTripper, error) { return nil, fmt.Errorf("using a custom transport with TLS certificate options or the insecure flag is not allowed") } - if !isValidHolders(config) { - return nil, fmt.Errorf("misconfigured holder for dialer or cert callback") - } - var ( rt http.RoundTripper err error @@ -61,26 +56,6 @@ func New(config *Config) (http.RoundTripper, error) { return HTTPWrappersForConfig(config, rt) } -func isValidHolders(config *Config) bool { - if config.TLS.GetCertHolder != nil { - if config.TLS.GetCertHolder.GetCert == nil || - config.TLS.GetCert == nil || - reflect.ValueOf(config.TLS.GetCertHolder.GetCert).Pointer() != reflect.ValueOf(config.TLS.GetCert).Pointer() { - return false - } - } - - if config.DialHolder != nil { - if config.DialHolder.Dial == nil || - config.Dial == nil || - reflect.ValueOf(config.DialHolder.Dial).Pointer() != reflect.ValueOf(config.Dial).Pointer() { - return false - } - } - - return true -} - // TLSConfigFor returns a tls.Config that will provide the transport level security defined // by the provided Config. Will return nil if no transport level security is requested. func TLSConfigFor(c *Config) (*tls.Config, error) { diff --git a/vendor/modules.txt b/vendor/modules.txt index e241daafc..e26602bf2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -81,8 +81,8 @@ github.com/google/gnostic/extensions github.com/google/gnostic/jsonschema github.com/google/gnostic/openapiv2 github.com/google/gnostic/openapiv3 -# github.com/google/go-cmp v0.5.8 -## explicit; go 1.13 +# github.com/google/go-cmp v0.5.6 +## explicit; go 1.8 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags @@ -245,7 +245,7 @@ github.com/openshift/client-go/operator/informers/externalversions/operator/v1 github.com/openshift/client-go/operator/informers/externalversions/operator/v1alpha1 github.com/openshift/client-go/operator/listers/operator/v1 github.com/openshift/client-go/operator/listers/operator/v1alpha1 -# github.com/openshift/library-go v0.0.0-20221017091500-9aea380195f4 +# github.com/openshift/library-go v0.0.0-20221017195819-7f7c08fa1941 ## explicit; go 1.18 github.com/openshift/library-go/pkg/authorization/hardcodedauthorizer github.com/openshift/library-go/pkg/config/client @@ -587,7 +587,7 @@ gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.1 ## explicit gopkg.in/yaml.v3 -# k8s.io/api v0.25.1 +# k8s.io/api v0.25.0 ## explicit; go 1.19 k8s.io/api/admission/v1 k8s.io/api/admission/v1beta1 @@ -647,7 +647,7 @@ k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1 k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1 -# k8s.io/apimachinery v0.25.1 +# k8s.io/apimachinery v0.25.0 ## explicit; go 1.19 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -833,7 +833,7 @@ k8s.io/apiserver/plugin/pkg/audit/truncate k8s.io/apiserver/plugin/pkg/audit/webhook k8s.io/apiserver/plugin/pkg/authenticator/token/webhook k8s.io/apiserver/plugin/pkg/authorizer/webhook -# k8s.io/client-go v0.25.1 +# k8s.io/client-go v0.25.0 ## explicit; go 1.19 k8s.io/client-go/applyconfigurations/admissionregistration/v1 k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1 @@ -1117,7 +1117,7 @@ k8s.io/client-go/util/homedir k8s.io/client-go/util/keyutil k8s.io/client-go/util/retry k8s.io/client-go/util/workqueue -# k8s.io/component-base v0.25.1 +# k8s.io/component-base v0.25.0 ## explicit; go 1.19 k8s.io/component-base/cli k8s.io/component-base/cli/flag