diff --git a/go.mod b/go.mod index 40457b3a1..d4cf3218b 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( k8s.io/kube-aggregator v0.29.3 k8s.io/utils v0.0.0-20240310230437-4693a0247e57 open-cluster-management.io/addon-framework v0.9.1-0.20240416063208-ecb7f349df05 - open-cluster-management.io/api v0.13.1-0.20240411131856-8f6aa25f111c + open-cluster-management.io/api v0.13.1-0.20240419062633-aacb530ea4ad open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379 sigs.k8s.io/controller-runtime v0.17.3 sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96 diff --git a/go.sum b/go.sum index bf5a039d3..4164df3e8 100644 --- a/go.sum +++ b/go.sum @@ -425,8 +425,8 @@ k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0g k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= open-cluster-management.io/addon-framework v0.9.1-0.20240416063208-ecb7f349df05 h1:oj4IEyxmQFMxdpnOPE/Y7Xkyfkz4hGVkcYZ4dn8WtKU= open-cluster-management.io/addon-framework v0.9.1-0.20240416063208-ecb7f349df05/go.mod h1:K+/TwCUz2PZ7L+svaodw6029S/iPJ7eVX21F7NMw+Kw= -open-cluster-management.io/api v0.13.1-0.20240411131856-8f6aa25f111c h1:/iUoY6/PqBmcBq3v0+UBFvIcI39k/QPRGqpOv9XtDIc= -open-cluster-management.io/api v0.13.1-0.20240411131856-8f6aa25f111c/go.mod h1:CuCPEzXDvOyxBB0H1d1eSeajbHqaeGEKq9c63vQc63w= +open-cluster-management.io/api v0.13.1-0.20240419062633-aacb530ea4ad h1:DB3GpK5vzbGu9ss13bfodi8pGTkPcpdcLvOPEPMptTk= +open-cluster-management.io/api v0.13.1-0.20240419062633-aacb530ea4ad/go.mod h1:yrNuMMpciXjXPnj2yznb6LTyrGliiTrFZAJDp/Ck3c4= open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379 h1:8jXVHfgy+wgXq1mrWC1mTieoP77WsAAHNpzILMIzWB0= open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379/go.mod h1:w2OaxtCyegxeyFLU42UQ3oxUz01QdsBQkcHI17T/l48= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 h1:TgtAeesdhpm2SGwkQasmbeqDo8th5wOBA5h/AjTKA4I= diff --git a/manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml b/manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml index da46af2ad..189420b42 100644 --- a/manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml +++ b/manifests/cluster-manager/management/cluster-manager-manifestworkreplicaset-deployment.yaml @@ -46,15 +46,16 @@ spec: args: - "/work" - "manager" + {{ if .CloudEventsDriverEnabled }} - "--work-driver={{ .WorkDriver }}" - {{ if eq .WorkDriver "kube" }} + {{ if ne .WorkDriver "kube" }} + - "--cloudevents-client-id=work-controller-$(POD_NAME)" + - "--work-driver-config=/var/run/secrets/work/config.yaml" + {{ end }} + {{ end }} {{ if .HostedMode }} - "--kubeconfig=/var/run/secrets/hub/kubeconfig" {{ end }} - {{ else }} - - "--cloudevents-client-id=work-controller-$(POD_NAME)" - - "--work-driver-config=/var/run/secrets/hub/config.yaml" - {{ end }} env: - name: POD_NAME valueFrom: @@ -97,27 +98,25 @@ spec: volumeMounts: - name: tmpdir mountPath: /tmp - {{ if eq .WorkDriver "kube" }} {{ if .HostedMode }} - mountPath: /var/run/secrets/hub name: kubeconfig readOnly: true {{ end }} - {{ else }} - - mountPath: /var/run/secrets/hub + {{ if and .CloudEventsDriverEnabled (ne .WorkDriver "kube") }} + - mountPath: /var/run/secrets/work name: workdriverconfig readOnly: true {{ end }} volumes: - name: tmpdir emptyDir: { } - {{ if eq .WorkDriver "kube" }} {{ if .HostedMode }} - name: kubeconfig secret: secretName: work-controller-sa-kubeconfig {{ end }} - {{ else }} + {{ if and .CloudEventsDriverEnabled (ne .WorkDriver "kube") }} - name: workdriverconfig secret: secretName: work-driver-config diff --git a/manifests/config.go b/manifests/config.go index d92e9cb0b..4fd5782c9 100644 --- a/manifests/config.go +++ b/manifests/config.go @@ -19,6 +19,7 @@ type HubConfig struct { AddOnManagerImage string AddOnManagerEnabled bool MWReplicaSetEnabled bool + CloudEventsDriverEnabled bool WorkDriver string AutoApproveUsers string // ResourceRequirementResourceType is the resource requirement resource type for the cluster manager managed containers. diff --git a/pkg/operator/helpers/queuekey.go b/pkg/operator/helpers/queuekey.go index 90b8c3bd0..1280bdce0 100644 --- a/pkg/operator/helpers/queuekey.go +++ b/pkg/operator/helpers/queuekey.go @@ -36,14 +36,12 @@ const ( // ExternalManagedKubeConfigAgent is the secret name of kubeconfig secret to connecting to the managed cluster // Only applicable to SingletonHosted mode, agent uses it to connect to the managed cluster. ExternalManagedKubeConfigAgent = "external-managed-kubeconfig-agent" - // WorkDriverConfig is the secret name of work driver config to connect to work driver. - // Only applicable to non-kube work driver, hub controllers connect to work driver using this config. - WorkDriverConfig = "work-driver-config" RegistrationWebhookSecret = "registration-webhook-serving-cert" RegistrationWebhookService = "cluster-manager-registration-webhook" WorkWebhookSecret = "work-webhook-serving-cert" // #nosec G101 WorkWebhookService = "cluster-manager-work-webhook" + WorkDriverConfig = "work-driver-config" SignerSecret = "signer-secret" CaBundleConfigmap = "ca-bundle-configmap" diff --git a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go index ad598377a..b5e5cdfb1 100644 --- a/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go +++ b/pkg/operator/operators/clustermanager/controllers/clustermanagercontroller/clustermanager_controller.go @@ -138,7 +138,7 @@ func (n *clusterManagerController) sync(ctx context.Context, controllerContext f // default driver is kube workDriver := operatorapiv1.WorkDriverTypeKube - if clusterManager.Spec.WorkConfiguration.WorkDriver != "" { + if clusterManager.Spec.WorkConfiguration != nil && clusterManager.Spec.WorkConfiguration.WorkDriver != "" { workDriver = clusterManager.Spec.WorkConfiguration.WorkDriver } @@ -180,6 +180,7 @@ func (n *clusterManagerController) sync(ctx context.Context, controllerContext f } config.WorkFeatureGates, workFeatureMsgs = helpers.ConvertToFeatureGateFlags("Work", workFeatureGates, ocmfeature.DefaultHubWorkFeatureGates) config.MWReplicaSetEnabled = helpers.FeatureGateEnabled(workFeatureGates, ocmfeature.DefaultHubWorkFeatureGates, ocmfeature.ManifestWorkReplicaSet) + config.CloudEventsDriverEnabled = helpers.FeatureGateEnabled(workFeatureGates, ocmfeature.DefaultHubWorkFeatureGates, ocmfeature.CloudEventsDrivers) var addonFeatureGates []operatorapiv1.FeatureGate if clusterManager.Spec.AddOnManagerConfiguration != nil { diff --git a/pkg/work/hub/options.go b/pkg/work/hub/options.go index b98c15303..b33a19b65 100644 --- a/pkg/work/hub/options.go +++ b/pkg/work/hub/options.go @@ -13,7 +13,9 @@ type WorkHubManagerOptions struct { } func NewWorkHubManagerOptions() *WorkHubManagerOptions { - return &WorkHubManagerOptions{} + return &WorkHubManagerOptions{ + WorkDriver: "kube", + } } // AddFlags register and binds the default flags diff --git a/test/integration/operator/clustermanager_hosted_test.go b/test/integration/operator/clustermanager_hosted_test.go index f584fd90b..39f2c5837 100644 --- a/test/integration/operator/clustermanager_hosted_test.go +++ b/test/integration/operator/clustermanager_hosted_test.go @@ -497,7 +497,28 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() { if err != nil { return err } - clusterManager.Spec.WorkConfiguration.WorkDriver = work.ConfigTypeGRPC + featureGates := []operatorapiv1.FeatureGate{ + { + Feature: string(feature.ManifestWorkReplicaSet), + Mode: operatorapiv1.FeatureGateModeTypeEnable, + }, + { + Feature: string(feature.CloudEventsDrivers), + Mode: operatorapiv1.FeatureGateModeTypeEnable, + }, + } + if clusterManager.Spec.WorkConfiguration != nil { + for _, fg := range clusterManager.Spec.WorkConfiguration.FeatureGates { + if fg.Feature != string(feature.ManifestWorkReplicaSet) && + fg.Feature != string(feature.CloudEventsDrivers) { + featureGates = append(featureGates, fg) + } + } + } + clusterManager.Spec.WorkConfiguration = &operatorapiv1.WorkConfiguration{ + FeatureGates: featureGates, + WorkDriver: work.ConfigTypeGRPC, + } _, err = hostedOperatorClient.OperatorV1().ClusterManagers().Update( context.Background(), clusterManager, metav1.UpdateOptions{}) return err diff --git a/test/integration/operator/clustermanager_test.go b/test/integration/operator/clustermanager_test.go index 59f4b94c1..7679bb310 100644 --- a/test/integration/operator/clustermanager_test.go +++ b/test/integration/operator/clustermanager_test.go @@ -472,7 +472,28 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() { if err != nil { return err } - clusterManager.Spec.WorkConfiguration.WorkDriver = work.ConfigTypeGRPC + featureGates := []operatorapiv1.FeatureGate{ + { + Feature: string(feature.ManifestWorkReplicaSet), + Mode: operatorapiv1.FeatureGateModeTypeEnable, + }, + { + Feature: string(feature.CloudEventsDrivers), + Mode: operatorapiv1.FeatureGateModeTypeEnable, + }, + } + if clusterManager.Spec.WorkConfiguration != nil { + for _, fg := range clusterManager.Spec.WorkConfiguration.FeatureGates { + if fg.Feature != string(feature.ManifestWorkReplicaSet) && + fg.Feature != string(feature.CloudEventsDrivers) { + featureGates = append(featureGates, fg) + } + } + } + clusterManager.Spec.WorkConfiguration = &operatorapiv1.WorkConfiguration{ + FeatureGates: featureGates, + WorkDriver: work.ConfigTypeGRPC, + } _, err = operatorClient.OperatorV1().ClusterManagers().Update( context.Background(), clusterManager, metav1.UpdateOptions{}) return err diff --git a/vendor/modules.txt b/vendor/modules.txt index 442383842..75354f1cf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1507,7 +1507,7 @@ open-cluster-management.io/addon-framework/pkg/basecontroller/events open-cluster-management.io/addon-framework/pkg/basecontroller/factory open-cluster-management.io/addon-framework/pkg/index open-cluster-management.io/addon-framework/pkg/utils -# open-cluster-management.io/api v0.13.1-0.20240411131856-8f6aa25f111c +# open-cluster-management.io/api v0.13.1-0.20240419062633-aacb530ea4ad ## explicit; go 1.21 open-cluster-management.io/api/addon/v1alpha1 open-cluster-management.io/api/client/addon/clientset/versioned diff --git a/vendor/open-cluster-management.io/api/crdsv1beta1/0001_00_operator.open-cluster-management.io_klusterlets.crd.yaml b/vendor/open-cluster-management.io/api/crdsv1beta1/0001_00_operator.open-cluster-management.io_klusterlets.crd.yaml index c6c2b162a..88ff39ad6 100644 --- a/vendor/open-cluster-management.io/api/crdsv1beta1/0001_00_operator.open-cluster-management.io_klusterlets.crd.yaml +++ b/vendor/open-cluster-management.io/api/crdsv1beta1/0001_00_operator.open-cluster-management.io_klusterlets.crd.yaml @@ -118,6 +118,32 @@ spec: description: RegistrationConfiguration contains the configuration of registration type: object properties: + bootstrapKubeConfigs: + description: "BootstrapKubeConfigs defines the ordered list of bootstrap kubeconfigs. The order decides which bootstrap kubeconfig to use first when rebootstrap. \n When the agent loses the connection to the current hub over HubConnectionTimeoutSeconds, or the managedcluster CR is set `hubAcceptsClient=false` on the hub, the controller marks the related bootstrap kubeconfig as \"failed\". \n A failed bootstrapkubeconfig won't be used for the duration specified by SkipFailedBootstrapKubeConfigSeconds. But if the user updates the content of a failed bootstrapkubeconfig, the \"failed\" mark will be cleared." + type: object + properties: + localSecretsConfig: + description: LocalSecretsConfig include a list of secrets that contains the kubeconfigs for ordered bootstrap kubeconifigs. The secrets must be in the same namespace where the agent controller runs. + type: object + properties: + hubConnectionTimeoutSeconds: + description: HubConnectionTimeoutSeconds is used to set the timeout of connecting to the hub cluster. When agent loses the connection to the hub over the timeout seconds, the agent do a rebootstrap. By default is 10 mins. + type: integer + format: int32 + default: 600 + minimum: 180 + secretNames: + description: SecretNames is a list of secret names. The secrets are in the same namespace where the agent controller runs. + type: array + items: + type: string + type: + description: Type specifies the type of priority bootstrap kubeconfigs. By default, it is set to None, representing no priority bootstrap kubeconfigs are set. + type: string + default: None + enum: + - None + - LocalSecrets clientCertExpirationSeconds: description: clientCertExpirationSeconds represents the seconds of a client certificate to expire. If it is not set or 0, the default duration seconds will be set by the hub cluster. If the value is larger than the max signing duration seconds set on the hub cluster, the max signing duration seconds will be set. type: integer diff --git a/vendor/open-cluster-management.io/api/feature/feature.go b/vendor/open-cluster-management.io/api/feature/feature.go index 8bd2aef95..45d90b425 100644 --- a/vendor/open-cluster-management.io/api/feature/feature.go +++ b/vendor/open-cluster-management.io/api/feature/feature.go @@ -64,6 +64,10 @@ const ( // of clusters selected by a placement. For more info check ManifestWorkReplicaSet APIs ManifestWorkReplicaSet featuregate.Feature = "ManifestWorkReplicaSet" + // CloudEventsDrivers will enable the cloud events drivers (mqtt or grpc) for the hub controller, + // so that the controller can deliver manifestworks to the managed clusters via cloud events. + CloudEventsDrivers featuregate.Feature = "CloudEventsDrivers" + // RawFeedbackJsonString will make the work agent to return the feedback result as a json string if the result // is not a scalar value. RawFeedbackJsonString featuregate.Feature = "RawFeedbackJsonString" @@ -100,6 +104,7 @@ var DefaultHubAddonManagerFeatureGates = map[featuregate.Feature]featuregate.Fea var DefaultHubWorkFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ NilExecutorValidating: {Default: false, PreRelease: featuregate.Alpha}, ManifestWorkReplicaSet: {Default: false, PreRelease: featuregate.Alpha}, + CloudEventsDrivers: {Default: false, PreRelease: featuregate.Alpha}, } // DefaultSpokeWorkFeatureGates consists of all known ocm work feature keys for work agent. diff --git a/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml b/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml index 4896f275f..3ad8fb969 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml +++ b/vendor/open-cluster-management.io/api/operator/v1/0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml @@ -181,6 +181,51 @@ spec: description: RegistrationConfiguration contains the configuration of registration properties: + bootstrapKubeConfigs: + description: "BootstrapKubeConfigs defines the ordered list of + bootstrap kubeconfigs. The order decides which bootstrap kubeconfig + to use first when rebootstrap. \n When the agent loses the connection + to the current hub over HubConnectionTimeoutSeconds, or the + managedcluster CR is set `hubAcceptsClient=false` on the hub, + the controller marks the related bootstrap kubeconfig as \"failed\". + \n A failed bootstrapkubeconfig won't be used for the duration + specified by SkipFailedBootstrapKubeConfigSeconds. But if the + user updates the content of a failed bootstrapkubeconfig, the + \"failed\" mark will be cleared." + properties: + localSecretsConfig: + description: LocalSecretsConfig include a list of secrets + that contains the kubeconfigs for ordered bootstrap kubeconifigs. + The secrets must be in the same namespace where the agent + controller runs. + properties: + hubConnectionTimeoutSeconds: + default: 600 + description: HubConnectionTimeoutSeconds is used to set + the timeout of connecting to the hub cluster. When agent + loses the connection to the hub over the timeout seconds, + the agent do a rebootstrap. By default is 10 mins. + format: int32 + minimum: 180 + type: integer + secretNames: + description: SecretNames is a list of secret names. The + secrets are in the same namespace where the agent controller + runs. + items: + type: string + type: array + type: object + type: + default: None + description: Type specifies the type of priority bootstrap + kubeconfigs. By default, it is set to None, representing + no priority bootstrap kubeconfigs are set. + enum: + - None + - LocalSecrets + type: string + type: object clientCertExpirationSeconds: description: clientCertExpirationSeconds represents the seconds of a client certificate to expire. If it is not set or 0, the diff --git a/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go b/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go index ea97392d5..0a1e0ae33 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go +++ b/vendor/open-cluster-management.io/api/operator/v1/types_klusterlet.go @@ -162,6 +162,52 @@ type RegistrationConfiguration struct { // +optional // +kubebuilder:default:=100 KubeAPIBurst int32 `json:"kubeAPIBurst,omitempty"` + + // BootstrapKubeConfigs defines the ordered list of bootstrap kubeconfigs. The order decides which bootstrap kubeconfig to use first when rebootstrap. + // + // When the agent loses the connection to the current hub over HubConnectionTimeoutSeconds, or the managedcluster CR + // is set `hubAcceptsClient=false` on the hub, the controller marks the related bootstrap kubeconfig as "failed". + // + // A failed bootstrapkubeconfig won't be used for the duration specified by SkipFailedBootstrapKubeConfigSeconds. + // But if the user updates the content of a failed bootstrapkubeconfig, the "failed" mark will be cleared. + // +optional + BootstrapKubeConfigs BootstrapKubeConfigs `json:"bootstrapKubeConfigs,omitempty"` +} + +type TypeBootstrapKubeConfigs string + +const ( + LocalSecrets TypeBootstrapKubeConfigs = "LocalSecrets" + None TypeBootstrapKubeConfigs = "None" +) + +type BootstrapKubeConfigs struct { + // Type specifies the type of priority bootstrap kubeconfigs. + // By default, it is set to None, representing no priority bootstrap kubeconfigs are set. + // +required + // +kubebuilder:default:=None + // +kubebuilder:validation:Enum=None;LocalSecrets + Type TypeBootstrapKubeConfigs `json:"type,omitempty"` + + // LocalSecretsConfig include a list of secrets that contains the kubeconfigs for ordered bootstrap kubeconifigs. + // The secrets must be in the same namespace where the agent controller runs. + // +optional + LocalSecrets LocalSecretsConfig `json:"localSecretsConfig,omitempty"` +} + +type LocalSecretsConfig struct { + // SecretNames is a list of secret names. The secrets are in the same namespace where the agent controller runs. + // +required + // +kubebuilder:validation:minItems=2 + SecretNames []string `json:"secretNames"` + + // HubConnectionTimeoutSeconds is used to set the timeout of connecting to the hub cluster. + // When agent loses the connection to the hub over the timeout seconds, the agent do a rebootstrap. + // By default is 10 mins. + // +optional + // +kubebuilder:default:=600 + // +kubebuilder:validation:Minimum=180 + HubConnectionTimeoutSeconds int32 `json:"hubConnectionTimeoutSeconds,omitempty"` } type WorkAgentConfiguration struct { diff --git a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go index 7d4983e2b..fed805f8d 100644 --- a/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/open-cluster-management.io/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -163,6 +163,15 @@ func (WorkConfiguration) SwaggerDoc() map[string]string { return map_WorkConfiguration } +var map_BootstrapKubeConfigs = map[string]string{ + "type": "Type specifies the type of priority bootstrap kubeconfigs. By default, it is set to None, representing no priority bootstrap kubeconfigs are set.", + "localSecretsConfig": "LocalSecretsConfig include a list of secrets that contains the kubeconfigs for ordered bootstrap kubeconifigs. The secrets must be in the same namespace where the agent controller runs.", +} + +func (BootstrapKubeConfigs) SwaggerDoc() map[string]string { + return map_BootstrapKubeConfigs +} + var map_HubApiServerHostAlias = map[string]string{ "": "HubApiServerHostAlias holds the mapping between IP and hostname that will be injected as an entry in the pod's hosts file.", "ip": "IP address of the host file entry.", @@ -235,12 +244,22 @@ func (KlusterletStatus) SwaggerDoc() map[string]string { return map_KlusterletStatus } +var map_LocalSecretsConfig = map[string]string{ + "secretNames": "SecretNames is a list of secret names. The secrets are in the same namespace where the agent controller runs.", + "hubConnectionTimeoutSeconds": "HubConnectionTimeoutSeconds is used to set the timeout of connecting to the hub cluster. When agent loses the connection to the hub over the timeout seconds, the agent do a rebootstrap. By default is 10 mins.", +} + +func (LocalSecretsConfig) SwaggerDoc() map[string]string { + return map_LocalSecretsConfig +} + var map_RegistrationConfiguration = map[string]string{ "clientCertExpirationSeconds": "clientCertExpirationSeconds represents the seconds of a client certificate to expire. If it is not set or 0, the default duration seconds will be set by the hub cluster. If the value is larger than the max signing duration seconds set on the hub cluster, the max signing duration seconds will be set.", "featureGates": "FeatureGates represents the list of feature gates for registration If it is set empty, default feature gates will be used. If it is set, featuregate/Foo is an example of one item in FeatureGates:\n 1. If featuregate/Foo does not exist, registration-operator will discard it\n 2. If featuregate/Foo exists and is false by default. It is now possible to set featuregate/Foo=[false|true]\n 3. If featuregate/Foo exists and is true by default. If a cluster-admin upgrading from 1 to 2 wants to continue having featuregate/Foo=false,\n \the can set featuregate/Foo=false before upgrading. Let's say the cluster-admin wants featuregate/Foo=false.", "clusterAnnotations": "ClusterAnnotations is annotations with the reserve prefix \"agent.open-cluster-management.io\" set on ManagedCluster when creating only, other actors can update it afterwards.", "kubeAPIQPS": "KubeAPIQPS indicates the maximum QPS while talking with apiserver of hub cluster from the spoke cluster. If it is set empty, use the default value: 50", "kubeAPIBurst": "KubeAPIBurst indicates the maximum burst of the throttle while talking with apiserver of hub cluster from the spoke cluster. If it is set empty, use the default value: 100", + "bootstrapKubeConfigs": "BootstrapKubeConfigs defines the ordered list of bootstrap kubeconfigs. The order decides which bootstrap kubeconfig to use first when rebootstrap.\n\nWhen the agent loses the connection to the current hub over HubConnectionTimeoutSeconds, or the managedcluster CR is set `hubAcceptsClient=false` on the hub, the controller marks the related bootstrap kubeconfig as \"failed\".\n\nA failed bootstrapkubeconfig won't be used for the duration specified by SkipFailedBootstrapKubeConfigSeconds. But if the user updates the content of a failed bootstrapkubeconfig, the \"failed\" mark will be cleared.", } func (RegistrationConfiguration) SwaggerDoc() map[string]string {