diff --git a/Makefile b/Makefile index f25836d9..d90195bb 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ $(call add-crd-gen,workv1,./work/v1,./work/v1,./work/v1) $(call add-crd-gen,workv1alpha1,./work/v1alpha1,./work/v1alpha1,./work/v1alpha1) $(call add-crd-gen,operator,./operator/v1,./operator/v1,./operator/v1) $(call add-crd-gen,addonv1alpha1,./addon/v1alpha1,./addon/v1alpha1,./addon/v1alpha1) +$(call add-crd-gen,addonv1beta1,./addon/v1alpha1 ./addon/v1beta1,./addon/v1beta1,./addon/v1beta1) RUNTIME ?= podman RUNTIME_IMAGE_NAME ?= openshift-api-generator diff --git a/addon/v1alpha1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml b/addon/v1alpha1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml index fcc31e73..25e14b8b 100644 --- a/addon/v1alpha1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml +++ b/addon/v1alpha1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml @@ -376,6 +376,7 @@ spec: type: object supportedConfigs: description: |- + Deprecated: Will be removed and replaced with DefaultConfigs in v1beta1. supportedConfigs is a list of configuration types supported by add-on. An empty list means the add-on does not require configurations. The default is an empty list @@ -422,7 +423,7 @@ spec: add-on. properties: defaultconfigReferences: - description: defaultconfigReferences is a list of current add-on default + description: DefaultconfigReferences is a list of current add-on default configuration references. items: description: |- diff --git a/addon/v1alpha1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml b/addon/v1alpha1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml index 89879edb..c6a67629 100644 --- a/addon/v1alpha1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml +++ b/addon/v1alpha1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml @@ -243,9 +243,8 @@ spec: - name type: object lastObservedGeneration: - description: |- - Deprecated: Use LastAppliedConfig instead - lastObservedGeneration is the observed generation of the add-on configuration. + description: lastObservedGeneration is the observed generation + of the add-on configuration. format: int64 type: integer name: @@ -302,14 +301,16 @@ spec: create a csr for the addon agent with the registrationConfig. properties: signerName: - description: signerName is the name of signer that addon agent - will use to create csr. + description: |- + Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. + signerName is the name of signer that addon agent will use to create csr. maxLength: 571 minLength: 5 pattern: ^([a-z0-9][a-z0-9-]*[a-z0-9]\.)+[a-z]+\/[a-z0-9-\.]+$ type: string subject: description: |- + Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. subject is the user subject of the addon agent to be registered to the hub. If it is not set, the addon agent will have the default subject "subject": { diff --git a/addon/v1alpha1/types_clustermanagementaddon.go b/addon/v1alpha1/types_clustermanagementaddon.go index 117e5d4b..fa7ebb2f 100644 --- a/addon/v1alpha1/types_clustermanagementaddon.go +++ b/addon/v1alpha1/types_clustermanagementaddon.go @@ -45,6 +45,7 @@ type ClusterManagementAddOnSpec struct { // +optional AddOnConfiguration ConfigCoordinates `json:"addOnConfiguration,omitempty"` + // Deprecated: Will be removed and replaced with DefaultConfigs in v1beta1. // supportedConfigs is a list of configuration types supported by add-on. // An empty list means the add-on does not require configurations. // The default is an empty list @@ -110,7 +111,7 @@ type ConfigGroupResource struct { // resource of the add-on configuration. // +required // +kubebuilder:validation:Required - // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MinLength=1 Resource string `json:"resource"` } @@ -124,7 +125,7 @@ type ConfigReferent struct { // name of the add-on configuration. // +required // +kubebuilder:validation:Required - // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MinLength=1 Name string `json:"name"` } @@ -170,12 +171,12 @@ type PlacementRef struct { // Namespace is the namespace of the placement // +required // +kubebuilder:validation:Required - // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MinLength=1 Namespace string `json:"namespace"` // Name is the name of the placement // +required // +kubebuilder:validation:Required - // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MinLength=1 Name string `json:"name"` } @@ -194,7 +195,7 @@ type PlacementStrategy struct { // ClusterManagementAddOnStatus represents the current status of cluster management add-on. type ClusterManagementAddOnStatus struct { - // defaultconfigReferences is a list of current add-on default configuration references. + // DefaultconfigReferences is a list of current add-on default configuration references. // +optional DefaultConfigReferences []DefaultConfigReference `json:"defaultconfigReferences,omitempty"` // installProgression is a list of current add-on configuration references per placement. @@ -267,7 +268,7 @@ const ( AddonLifecycleAnnotationKey = "addon.open-cluster-management.io/lifecycle" // AddonLifecycleAddonManagerAnnotationValue is the value of annotation AddonLifecycleAnnotationKey indicating // that the addon installation and upgrade is handled by the general addon manager. This should be set only - // when featugate AddonManager on hub is enabled + // when featuregate AddonManager on hub is enabled AddonLifecycleAddonManagerAnnotationValue = "addon-manager" // AddonLifecycleSelfManageAnnotationValue is the value of annotation AddonLifecycleAnnotationKey indicating // that the addon installation and upgrade is handled the addon itself. The general addon manager will ignore diff --git a/addon/v1alpha1/types_managedclusteraddon.go b/addon/v1alpha1/types_managedclusteraddon.go index 53a85b6d..2ba69ad7 100644 --- a/addon/v1alpha1/types_managedclusteraddon.go +++ b/addon/v1alpha1/types_managedclusteraddon.go @@ -54,6 +54,7 @@ type ManagedClusterAddOnSpec struct { // RegistrationConfig defines the configuration of the addon agent to register to hub. The Klusterlet agent will // create a csr for the addon agent with the registrationConfig. type RegistrationConfig struct { + // Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. // signerName is the name of signer that addon agent will use to create csr. // +required // +kubebuilder:validation:MaxLength=571 @@ -61,6 +62,7 @@ type RegistrationConfig struct { // +kubebuilder:validation:Pattern=^([a-z0-9][a-z0-9-]*[a-z0-9]\.)+[a-z]+\/[a-z0-9-\.]+$ SignerName string `json:"signerName"` + // Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. // subject is the user subject of the addon agent to be registered to the hub. // If it is not set, the addon agent will have the default subject // "subject": { @@ -191,7 +193,6 @@ type ConfigReference struct { // defaultConfigs. ConfigReferent `json:",inline"` - // Deprecated: Use LastAppliedConfig instead // lastObservedGeneration is the observed generation of the add-on configuration. LastObservedGeneration int64 `json:"lastObservedGeneration"` diff --git a/addon/v1beta1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml b/addon/v1beta1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml new file mode 100644 index 00000000..23c40cf4 --- /dev/null +++ b/addon/v1beta1/0000_00_addon.open-cluster-management.io_clustermanagementaddons.crd.yaml @@ -0,0 +1,1212 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clustermanagementaddons.addon.open-cluster-management.io +spec: + group: addon.open-cluster-management.io + names: + kind: ClusterManagementAddOn + listKind: ClusterManagementAddOnList + plural: clustermanagementaddons + shortNames: + - cma + - cmas + singular: clustermanagementaddon + preserveUnknownFields: false + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.addOnMeta.displayName + name: DISPLAY NAME + type: string + - jsonPath: .spec.addOnConfiguration.crdName + name: CRD NAME + type: string + deprecated: true + deprecationWarning: addon.open-cluster-management.io/v1alpha1 ClusterManagementAddOn + is deprecated; use addon.open-cluster-management.io/v1beta1 ClusterManagementAddOn + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ClusterManagementAddOn represents the registration of an add-on to the cluster manager. + This resource allows you to discover which add-ons are available for the cluster manager + and provides metadata information about the add-ons. The ClusterManagementAddOn name is used + for the namespace-scoped ManagedClusterAddOn resource. + ClusterManagementAddOn is a cluster-scoped resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec represents a desired configuration for the agent on + the cluster management add-on. + properties: + addOnConfiguration: + description: |- + Deprecated: Use supportedConfigs filed instead + addOnConfiguration is a reference to configuration information for the add-on. + In scenario where a multiple add-ons share the same add-on CRD, multiple ClusterManagementAddOn + resources need to be created and reference the same AddOnConfiguration. + properties: + crName: + description: |- + crName is the name of the CR used to configure instances of the managed add-on. + This field should be configured if add-on CR have a consistent name across the all of the ManagedCluster instaces. + type: string + crdName: + description: |- + crdName is the name of the CRD used to configure instances of the managed add-on. + This field should be configured if the add-on have a CRD that controls the configuration of the add-on. + type: string + lastObservedGeneration: + description: lastObservedGeneration is the observed generation + of the custom resource for the configuration of the addon. + format: int64 + type: integer + type: object + addOnMeta: + description: addOnMeta is a reference to the metadata information + for the add-on. + properties: + description: + description: description represents the detailed description of + the add-on. + type: string + displayName: + description: displayName represents the name of add-on that will + be displayed. + type: string + type: object + installStrategy: + default: + type: Manual + description: |- + InstallStrategy represents that related ManagedClusterAddOns should be installed + on certain clusters. + properties: + placements: + description: |- + Placements is a list of placement references honored when install strategy type is + Placements. All clusters selected by these placements will install the addon + If one cluster belongs to multiple placements, it will only apply the strategy defined + later in the order. That is to say, The latter strategy overrides the previous one. + items: + properties: + configs: + description: |- + Configs is the configuration of managedClusterAddon during installation. + User can override the configuration by updating the managedClusterAddon directly. + items: + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + name: + description: Name is the name of the placement + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the placement + minLength: 1 + type: string + rolloutStrategy: + default: + type: All + description: |- + The rollout strategy to apply addon configurations change. + The rollout strategy only watches the addon configurations defined in ClusterManagementAddOn. + properties: + all: + description: all defines required fields for RolloutStrategy + type All + properties: + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + progressive: + description: progressive defines required fields for + RolloutStrategy type Progressive + properties: + mandatoryDecisionGroups: + description: |- + List of the decision groups names or indexes to apply the workload first and fail if workload + did not reach successful state. + GroupName or GroupIndex must match with the decisionGroups defined in the placement's + decisionStrategy + items: + description: |- + MandatoryDecisionGroup set the decision group name or group index. + GroupName is considered first to select the decisionGroups then GroupIndex. + properties: + groupIndex: + description: |- + groupIndex of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-index + format: int32 + type: integer + groupName: + description: |- + groupName of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-name + type: string + type: object + type: array + maxConcurrency: + anyOf: + - type: integer + - type: string + description: |- + maxConcurrency is the max number of clusters to deploy workload concurrently. The default value + for MaxConcurrency is determined from the clustersPerDecisionGroup defined in the + placement->DecisionStrategy. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + progressivePerGroup: + description: progressivePerGroup defines required fields + for RolloutStrategy type ProgressivePerGroup + properties: + mandatoryDecisionGroups: + description: |- + List of the decision groups names or indexes to apply the workload first and fail if workload + did not reach successful state. + GroupName or GroupIndex must match with the decisionGroups defined in the placement's + decisionStrategy + items: + description: |- + MandatoryDecisionGroup set the decision group name or group index. + GroupName is considered first to select the decisionGroups then GroupIndex. + properties: + groupIndex: + description: |- + groupIndex of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-index + format: int32 + type: integer + groupName: + description: |- + groupName of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-name + type: string + type: object + type: array + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + type: + default: All + enum: + - All + - Progressive + - ProgressivePerGroup + type: string + type: object + required: + - name + - namespace + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + type: + default: Manual + description: |- + Type is the type of the install strategy, it can be: + - Manual: no automatic install + - Placements: install to clusters selected by placements. + enum: + - Manual + - Placements + type: string + type: object + supportedConfigs: + description: |- + Deprecated: Will be removed and replaced with DefaultConfigs in v1beta1. + supportedConfigs is a list of configuration types supported by add-on. + An empty list means the add-on does not require configurations. + The default is an empty list + items: + description: ConfigMeta represents a collection of metadata information + for add-on configuration. + properties: + defaultConfig: + description: |- + defaultConfig represents the namespace and name of the default add-on configuration. + In scenario where all add-ons have a same configuration. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + x-kubernetes-list-type: map + type: object + status: + description: status represents the current status of cluster management + add-on. + properties: + defaultconfigReferences: + description: DefaultconfigReferences is a list of current add-on default + configuration references. + items: + description: |- + DefaultConfigReference is a reference to the current add-on configuration. + This resource is used to record the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + installProgressions: + description: installProgression is a list of current add-on configuration + references per placement. + items: + properties: + conditions: + description: conditions describe the state of the managed and + monitored components for the operator. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + configReferences: + description: configReferences is a list of current add-on configuration + references. + items: + description: |- + InstallConfigReference is a reference to the current add-on configuration. + This resource is used to record the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config name + and spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + lastAppliedConfig: + description: |- + lastAppliedConfig records the config spec hash when the all the corresponding + ManagedClusterAddOn are applied successfully. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + lastKnownGoodConfig: + description: |- + lastKnownGoodConfig records the last known good config spec hash. + For fresh install or rollout with type UpdateAll or RollingUpdate, the + lastKnownGoodConfig is the same as lastAppliedConfig. + For rollout with type RollingUpdateWithCanary, the lastKnownGoodConfig + is the last successfully applied config spec hash of the canary placement. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + name: + description: Name is the name of the placement + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the placement + minLength: 1 + type: string + required: + - name + - namespace + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.addOnMeta.displayName + name: DISPLAY NAME + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + ClusterManagementAddOn represents the registration of an add-on to the cluster manager. + This resource allows you to discover which add-ons are available for the cluster manager + and provides metadata information about the add-ons. The ClusterManagementAddOn name is used + for the namespace-scoped ManagedClusterAddOn resource. + ClusterManagementAddOn is a cluster-scoped resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec represents a desired configuration for the agent on + the cluster management add-on. + properties: + addOnMeta: + description: addOnMeta is a reference to the metadata information + for the add-on. + properties: + description: + description: description represents the detailed description of + the add-on. + type: string + displayName: + description: displayName represents the name of add-on that will + be displayed. + type: string + type: object + defaultConfigs: + description: DefaultConfigs is a list of default configuration types + supported by add-on. + items: + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + x-kubernetes-list-type: map + installStrategy: + default: + type: Manual + description: |- + InstallStrategy represents that related ManagedClusterAddOns should be installed + on certain clusters. + properties: + placements: + description: |- + Placements is a list of placement references honored when install strategy type is + Placements. All clusters selected by these placements will install the addon + If one cluster belongs to multiple placements, it will only apply the strategy defined + later in the order. That is to say, The latter strategy overrides the previous one. + items: + properties: + configs: + description: |- + Configs is the configuration of managedClusterAddon during installation. + User can override the configuration by updating the managedClusterAddon directly. + items: + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + name: + description: Name is the name of the placement + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the placement + minLength: 1 + type: string + rolloutStrategy: + default: + type: All + description: |- + The rollout strategy to apply addon configurations change. + The rollout strategy only watches the addon configurations defined in ClusterManagementAddOn. + properties: + all: + description: all defines required fields for RolloutStrategy + type All + properties: + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + progressive: + description: progressive defines required fields for + RolloutStrategy type Progressive + properties: + mandatoryDecisionGroups: + description: |- + List of the decision groups names or indexes to apply the workload first and fail if workload + did not reach successful state. + GroupName or GroupIndex must match with the decisionGroups defined in the placement's + decisionStrategy + items: + description: |- + MandatoryDecisionGroup set the decision group name or group index. + GroupName is considered first to select the decisionGroups then GroupIndex. + properties: + groupIndex: + description: |- + groupIndex of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-index + format: int32 + type: integer + groupName: + description: |- + groupName of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-name + type: string + type: object + type: array + maxConcurrency: + anyOf: + - type: integer + - type: string + description: |- + maxConcurrency is the max number of clusters to deploy workload concurrently. The default value + for MaxConcurrency is determined from the clustersPerDecisionGroup defined in the + placement->DecisionStrategy. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + progressivePerGroup: + description: progressivePerGroup defines required fields + for RolloutStrategy type ProgressivePerGroup + properties: + mandatoryDecisionGroups: + description: |- + List of the decision groups names or indexes to apply the workload first and fail if workload + did not reach successful state. + GroupName or GroupIndex must match with the decisionGroups defined in the placement's + decisionStrategy + items: + description: |- + MandatoryDecisionGroup set the decision group name or group index. + GroupName is considered first to select the decisionGroups then GroupIndex. + properties: + groupIndex: + description: |- + groupIndex of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-index + format: int32 + type: integer + groupName: + description: |- + groupName of the decision group should match the placementDecisions label value with label key + cluster.open-cluster-management.io/decision-group-name + type: string + type: object + type: array + maxFailures: + anyOf: + - type: integer + - type: string + default: 0 + description: |- + MaxFailures is a percentage or number of clusters in the current rollout that can fail before + proceeding to the next rollout. Fail means the cluster has a failed status or timeout status + (does not reach successful status after ProgressDeadline). + Once the MaxFailures is breached, the rollout will stop. + MaxFailures is only considered for rollout types Progressive and ProgressivePerGroup. For + Progressive, this is considered over the total number of clusters. For ProgressivePerGroup, + this is considered according to the size of the current group. For both Progressive and + ProgressivePerGroup, the MaxFailures does not apply for MandatoryDecisionGroups, which tolerate + no failures. + Default is that no failures are tolerated. + pattern: ^((100|[0-9]{1,2})%|[0-9]+)$ + x-kubernetes-int-or-string: true + minSuccessTime: + default: "0" + description: |- + MinSuccessTime is a "soak" time. In other words, the minimum amount of time the workload + applier controller will wait from the start of each rollout before proceeding (assuming a + successful state has been reached and MaxFailures wasn't breached). + MinSuccessTime is only considered for rollout types Progressive and ProgressivePerGroup. + The default value is 0 meaning the workload applier proceeds immediately after a successful + state is reached. + MinSuccessTime must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + type: string + progressDeadline: + default: None + description: |- + ProgressDeadline defines how long workload applier controller will wait for the workload to + reach a successful state in the cluster. + If the workload does not reach a successful state after ProgressDeadline, will stop waiting + and workload will be treated as "timeout" and be counted into MaxFailures. Once the MaxFailures + is breached, the rollout will stop. + ProgressDeadline default value is "None", meaning the workload applier will wait for a + successful state indefinitely. + ProgressDeadline must be defined in [0-9h]|[0-9m]|[0-9s] format examples; 2h , 90m , 360s + pattern: ^(([0-9])+[h|m|s])|None$ + type: string + type: object + type: + default: All + enum: + - All + - Progressive + - ProgressivePerGroup + type: string + type: object + required: + - name + - namespace + type: object + type: array + x-kubernetes-list-map-keys: + - namespace + - name + x-kubernetes-list-type: map + type: + default: Manual + description: |- + Type is the type of the install strategy, it can be: + - Manual: no automatic install + - Placements: install to clusters selected by placements. + enum: + - Manual + - Placements + type: string + type: object + type: object + status: + description: status represents the current status of cluster management + add-on. + properties: + defaultconfigReferences: + description: DefaultconfigReferences is a list of current add-on default + configuration references. + items: + description: |- + DefaultConfigReference is a reference to the current add-on configuration. + This resource is used to record the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + installProgressions: + description: installProgression is a list of current add-on configuration + references per placement. + items: + properties: + conditions: + description: conditions describe the state of the managed and + monitored components for the operator. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + configReferences: + description: configReferences is a list of current add-on configuration + references. + items: + description: |- + InstallConfigReference is a reference to the current add-on configuration. + This resource is used to record the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config name + and spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + lastAppliedConfig: + description: |- + lastAppliedConfig records the config spec hash when the all the corresponding + ManagedClusterAddOn are applied successfully. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + lastKnownGoodConfig: + description: |- + lastKnownGoodConfig records the last known good config spec hash. + For fresh install or rollout with type UpdateAll or RollingUpdate, the + lastKnownGoodConfig is the same as lastAppliedConfig. + For rollout with type RollingUpdateWithCanary, the lastKnownGoodConfig + is the last successfully applied config spec hash of the canary placement. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + name: + description: Name is the name of the placement + minLength: 1 + type: string + namespace: + description: Namespace is the namespace of the placement + minLength: 1 + type: string + required: + - name + - namespace + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/addon/v1beta1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml b/addon/v1beta1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml new file mode 100644 index 00000000..78a53db8 --- /dev/null +++ b/addon/v1beta1/0000_01_addon.open-cluster-management.io_managedclusteraddons.crd.yaml @@ -0,0 +1,784 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: managedclusteraddons.addon.open-cluster-management.io +spec: + group: addon.open-cluster-management.io + names: + kind: ManagedClusterAddOn + listKind: ManagedClusterAddOnList + plural: managedclusteraddons + shortNames: + - mca + - mcas + singular: managedclusteraddon + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Available")].status + name: Available + type: string + - jsonPath: .status.conditions[?(@.type=="Degraded")].status + name: Degraded + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].status + name: Progressing + type: string + deprecated: true + deprecationWarning: addon.open-cluster-management.io/v1alpha1 ManagedClusterAddOn + is deprecated; use addon.open-cluster-management.io/v1beta1 ManagedClusterAddOn + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ManagedClusterAddOn is the Custom Resource object which holds the current state + of an add-on. This object is used by add-on operators to convey their state. + This resource should be created in the ManagedCluster namespace. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds configuration that could apply to any operator. + properties: + configs: + description: |- + configs is a list of add-on configurations. + In scenario where the current add-on has its own configurations. + An empty list means there are no default configurations for add-on. + The default is an empty list + items: + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + installNamespace: + default: open-cluster-management-agent-addon + description: |- + Deprecated: Use AddonDeploymentConfig instead. + installNamespace is the namespace on the managed cluster to install the addon agent. + If it is not set, open-cluster-management-agent-addon namespace is used to install the addon agent. + maxLength: 63 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + type: object + status: + description: |- + status holds the information about the state of an operator. It is consistent with status information across + the Kubernetes ecosystem. + properties: + addOnConfiguration: + description: |- + Deprecated: Use configReferences instead. + addOnConfiguration is a reference to configuration information for the add-on. + This resource is used to locate the configuration resource for the add-on. + properties: + crName: + description: |- + crName is the name of the CR used to configure instances of the managed add-on. + This field should be configured if add-on CR have a consistent name across the all of the ManagedCluster instaces. + type: string + crdName: + description: |- + crdName is the name of the CRD used to configure instances of the managed add-on. + This field should be configured if the add-on have a CRD that controls the configuration of the add-on. + type: string + lastObservedGeneration: + description: lastObservedGeneration is the observed generation + of the custom resource for the configuration of the addon. + format: int64 + type: integer + type: object + addOnMeta: + description: |- + addOnMeta is a reference to the metadata information for the add-on. + This should be same as the addOnMeta for the corresponding ClusterManagementAddOn resource. + properties: + description: + description: description represents the detailed description of + the add-on. + type: string + displayName: + description: displayName represents the name of add-on that will + be displayed. + type: string + type: object + conditions: + description: conditions describe the state of the managed and monitored + components for the operator. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + configReferences: + description: |- + configReferences is a list of current add-on configuration references. + This will be overridden by the clustermanagementaddon configuration references. + items: + description: |- + ConfigReference is a reference to the current add-on configuration. + This resource is used to locate the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + lastAppliedConfig: + description: lastAppliedConfig record the config spec hash when + the corresponding ManifestWork is applied successfully. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + lastObservedGeneration: + description: lastObservedGeneration is the observed generation + of the add-on configuration. + format: int64 + type: integer + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + healthCheck: + description: |- + healthCheck indicates how to check the healthiness status of the current addon. It should be + set by each addon implementation, by default, the lease mode will be used. + properties: + mode: + default: Lease + description: mode indicates which mode will be used to check the + healthiness status of the addon. + enum: + - Lease + - Customized + type: string + type: object + namespace: + description: |- + namespace is the namespace on the managedcluster to put registration secret or lease for the addon. It is + required when registration is set or healthcheck mode is Lease. + type: string + registrations: + description: |- + registrations is the configurations for the addon agent to register to hub. It should be set by each addon controller + on hub to define how the addon agent on managedcluster is registered. With the registration defined, + The addon agent can access to kube apiserver with kube style API or other endpoints on hub cluster with client + certificate authentication. A csr will be created per registration configuration. If more than one + registrationConfig is defined, a csr will be created for each registration configuration. It is not allowed that + multiple registrationConfigs have the same signer name. After the csr is approved on the hub cluster, the klusterlet + agent will create a secret in the installNamespace for the registrationConfig. If the signerName is + "kubernetes.io/kube-apiserver-client", the secret name will be "{addon name}-hub-kubeconfig" whose contents includes + key/cert and kubeconfig. Otherwise, the secret name will be "{addon name}-{signer name}-client-cert" whose contents includes key/cert. + items: + description: |- + RegistrationConfig defines the configuration of the addon agent to register to hub. The Klusterlet agent will + create a csr for the addon agent with the registrationConfig. + properties: + signerName: + description: |- + Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. + signerName is the name of signer that addon agent will use to create csr. + maxLength: 571 + minLength: 5 + pattern: ^([a-z0-9][a-z0-9-]*[a-z0-9]\.)+[a-z]+\/[a-z0-9-\.]+$ + type: string + subject: + description: |- + Deprecated: Will be replaced with type: kubeClient and type: csr in v1beta1. + subject is the user subject of the addon agent to be registered to the hub. + If it is not set, the addon agent will have the default subject + "subject": { + "user": "system:open-cluster-management:cluster:{clusterName}:addon:{addonName}:agent:{agentName}", + "groups: ["system:open-cluster-management:cluster:{clusterName}:addon:{addonName}", + "system:open-cluster-management:addon:{addonName}", "system:authenticated"] + } + properties: + groups: + description: groups is the user group of the addon agent. + items: + type: string + type: array + organizationUnit: + description: organizationUnit is the ou of the addon agent + items: + type: string + type: array + user: + description: user is the user name of the addon agent. + type: string + type: object + required: + - signerName + type: object + type: array + relatedObjects: + description: |- + relatedObjects is a list of objects that are "interesting" or related to this operator. Common uses are: + 1. the detailed resource driving the operator + 2. operator namespaces + 3. operand namespaces + 4. related ClusterManagementAddon resource + items: + description: ObjectReference contains enough information to let + you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + type: array + supportedConfigs: + description: |- + SupportedConfigs is a list of configuration types that are allowed to override the add-on configurations defined + in ClusterManagementAddOn spec. + The default is an empty list, which means the add-on configurations can not be overridden. + items: + description: ConfigGroupResource represents the GroupResource of + the add-on configuration + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=="Available")].status + name: Available + type: string + - jsonPath: .status.conditions[?(@.type=="Degraded")].status + name: Degraded + type: string + - jsonPath: .status.conditions[?(@.type=="Progressing")].status + name: Progressing + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + ManagedClusterAddOn is the Custom Resource object which holds the current state + of an add-on. This object is used by add-on operators to convey their state. + This resource should be created in the ManagedCluster namespace. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec holds configuration that could apply to any operator. + properties: + configs: + description: |- + configs is a list of add-on configurations. + In scenario where the current add-on has its own configurations. + An empty list means there are no default configurations for add-on. + The default is an empty list + items: + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - name + - resource + type: object + type: array + type: object + status: + description: |- + status holds the information about the state of an operator. It is consistent with status information across + the Kubernetes ecosystem. + properties: + addOnMeta: + description: |- + addOnMeta is a reference to the metadata information for the add-on. + This should be same as the addOnMeta for the corresponding ClusterManagementAddOn resource. + properties: + description: + description: description represents the detailed description of + the add-on. + type: string + displayName: + description: displayName represents the name of add-on that will + be displayed. + type: string + type: object + conditions: + description: conditions describe the state of the managed and monitored + components for the operator. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + configReferences: + description: |- + configReferences is a list of current add-on configuration references. + This will be overridden by the clustermanagementaddon configuration references. + items: + description: |- + ConfigReference is a reference to the current add-on configuration. + This resource is used to locate the configuration resource for the current add-on. + properties: + desiredConfig: + description: desiredConfig record the desired config spec hash. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + group: + default: "" + description: group of the add-on configuration. + type: string + lastAppliedConfig: + description: lastAppliedConfig record the config spec hash when + the corresponding ManifestWork is applied successfully. + properties: + name: + description: name of the add-on configuration. + minLength: 1 + type: string + namespace: + description: |- + namespace of the add-on configuration. + If this field is not set, the configuration is in the cluster scope. + type: string + specHash: + description: spec hash for an add-on configuration. + type: string + required: + - name + type: object + lastObservedGeneration: + description: lastObservedGeneration is the observed generation + of the add-on configuration. + format: int64 + type: integer + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + healthCheck: + description: |- + healthCheck indicates how to check the healthiness status of the current addon. It should be + set by each addon implementation, by default, the lease mode will be used. + properties: + mode: + default: Lease + description: mode indicates which mode will be used to check the + healthiness status of the addon. + enum: + - Lease + - Customized + type: string + type: object + namespace: + description: |- + namespace is the namespace on the managedcluster to put registration secret or lease for the addon. It is + required when registration is set or healthcheck mode is Lease. + type: string + registrations: + description: |- + registrations is the configurations for the addon agent to register to hub. It should be set by each addon controller + on hub to define how the addon agent on managedcluster is registered. With the registration defined, + The addon agent can access to kube apiserver with kube style API or other endpoints on hub cluster with client + certificate authentication. A csr will be created per registration configuration. If more than one + registrationConfig is defined, a csr will be created for each registration configuration. It is not allowed that + multiple registrationConfigs have the same signer name. After the csr is approved on the hub cluster, the klusterlet + agent will create a secret in the installNamespace for the registrationConfig. If the signerName is + "kubernetes.io/kube-apiserver-client", the secret name will be "{addon name}-hub-kubeconfig" whose contents includes + key/cert and kubeconfig. Otherwise, the secret name will be "{addon name}-{signer name}-client-cert" whose contents includes key/cert. + items: + description: RegistrationConfig defines the configuration for the + addon agent to register to the hub cluster. + properties: + csr: + description: |- + csr holds the configuration for CSR type registration. + It should be set when type is "CSR". + properties: + signerName: + description: signerName is the name of signer that addon + agent will use to create csr. + maxLength: 571 + minLength: 5 + pattern: ^([a-z0-9][a-z0-9-]*[a-z0-9]\.)+[a-z]+\/[a-z0-9-\.]+$ + type: string + subject: + description: subject is the user subject of the addon agent + to be registered to the hub. + properties: + groups: + description: groups is the user group of the addon agent. + items: + type: string + type: array + organizationUnit: + description: organizationUnit is the ou of the addon + agent + items: + type: string + type: array + user: + description: user is the user name of the addon agent. + type: string + type: object + required: + - signerName + type: object + kubeClient: + description: |- + kubeClient holds the configuration for KubeClient type registration. + It should be set when type is "KubeClient". + properties: + subject: + description: subject is the user subject of the addon agent + to be registered to the hub. + properties: + groups: + description: groups is the user group of the addon agent. + items: + type: string + type: array + organizationUnit: + description: organizationUnit is the ou of the addon + agent + items: + type: string + type: array + user: + description: user is the user name of the addon agent. + type: string + type: object + type: object + type: + description: type specifies the type of registration configuration. + enum: + - KubeClient + - CSR + type: string + required: + - type + type: object + type: array + relatedObjects: + description: |- + relatedObjects is a list of objects that are "interesting" or related to this operator. Common uses are: + 1. the detailed resource driving the operator + 2. operator namespaces + 3. operand namespaces + 4. related ClusterManagementAddon resource + items: + description: ObjectReference contains enough information to let + you inspect or modify the referred object. + properties: + group: + description: group of the referent. + type: string + name: + description: name of the referent. + type: string + namespace: + description: namespace of the referent. + type: string + resource: + description: resource of the referent. + type: string + required: + - group + - name + - resource + type: object + type: array + supportedConfigs: + description: |- + SupportedConfigs is a list of configuration types that are allowed to override the add-on configurations defined + in ClusterManagementAddOn spec. + The default is an empty list, which means the add-on configurations can not be overridden. + items: + description: ConfigGroupResource represents the GroupResource of + the add-on configuration + properties: + group: + default: "" + description: group of the add-on configuration. + type: string + resource: + description: resource of the add-on configuration. + minLength: 1 + type: string + required: + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/addon/v1beta1/doc.go b/addon/v1beta1/doc.go new file mode 100644 index 00000000..5d5abb5e --- /dev/null +++ b/addon/v1beta1/doc.go @@ -0,0 +1,8 @@ +// Copyright Contributors to the Open Cluster Management project +// Package v1beta1 contains API Schema definitions for the addon v1beta1 API group +// +k8s:deepcopy-gen=package,register +// +k8s:openapi-gen=true + +// +kubebuilder:validation:Optional +// +groupName=addon.open-cluster-management.io +package v1beta1 diff --git a/addon/v1beta1/register.go b/addon/v1beta1/register.go new file mode 100644 index 00000000..27ff94aa --- /dev/null +++ b/addon/v1beta1/register.go @@ -0,0 +1,41 @@ +// Copyright Contributors to the Open Cluster Management project +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + GroupName = "addon.open-cluster-management.io" + GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // Install is a function which adds this version to a scheme + Install = schemeBuilder.AddToScheme + + // SchemeGroupVersion generated code relies on this name + // Deprecated + SchemeGroupVersion = GroupVersion + // AddToScheme exists solely to keep the old generators creating valid code + // DEPRECATED + AddToScheme = schemeBuilder.AddToScheme +) + +// Resource generated code relies on this being here, but it logically belongs to the group +// DEPRECATED +func Resource(resource string) schema.GroupResource { + return schema.GroupResource{Group: GroupName, Resource: resource} +} + +// Adds the list of known types to api.Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, + &ClusterManagementAddOn{}, + &ClusterManagementAddOnList{}, + &ManagedClusterAddOn{}, + &ManagedClusterAddOnList{}, + ) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/addon/v1beta1/types_clustermanagementaddon.go b/addon/v1beta1/types_clustermanagementaddon.go new file mode 100644 index 00000000..d61979b0 --- /dev/null +++ b/addon/v1beta1/types_clustermanagementaddon.go @@ -0,0 +1,238 @@ +// Copyright Contributors to the Open Cluster Management project +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clusterv1alpha1 "open-cluster-management.io/api/cluster/v1alpha1" +) + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope="Cluster",shortName={"cma","cmas"} +// +kubebuilder:printcolumn:name="DISPLAY NAME",type=string,JSONPath=`.spec.addOnMeta.displayName` + +// ClusterManagementAddOn represents the registration of an add-on to the cluster manager. +// This resource allows you to discover which add-ons are available for the cluster manager +// and provides metadata information about the add-ons. The ClusterManagementAddOn name is used +// for the namespace-scoped ManagedClusterAddOn resource. +// ClusterManagementAddOn is a cluster-scoped resource. +type ClusterManagementAddOn struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // spec represents a desired configuration for the agent on the cluster management add-on. + // +required + Spec ClusterManagementAddOnSpec `json:"spec"` + + // status represents the current status of cluster management add-on. + // +optional + Status ClusterManagementAddOnStatus `json:"status,omitempty"` +} + +// ClusterManagementAddOnSpec provides information for the add-on. +type ClusterManagementAddOnSpec struct { + // addOnMeta is a reference to the metadata information for the add-on. + // +optional + AddOnMeta AddOnMeta `json:"addOnMeta,omitempty"` + + // DefaultConfigs is a list of default configuration types supported by add-on. + // +optional + // +listType=map + // +listMapKey=group + // +listMapKey=resource + DefaultConfigs []AddOnConfig `json:"defaultConfigs,omitempty"` + + // InstallStrategy represents that related ManagedClusterAddOns should be installed + // on certain clusters. + // +optional + // +kubebuilder:default={type: Manual} + InstallStrategy InstallStrategy `json:"installStrategy,omitempty"` +} + +// AddOnMeta represents a collection of metadata information for the add-on. +type AddOnMeta struct { + // displayName represents the name of add-on that will be displayed. + // +optional + DisplayName string `json:"displayName,omitempty"` + + // description represents the detailed description of the add-on. + // +optional + Description string `json:"description,omitempty"` +} + +// ConfigGroupResource represents the GroupResource of the add-on configuration +type ConfigGroupResource struct { + // group of the add-on configuration. + // +optional + // +kubebuilder:default="" + Group string `json:"group"` + + // resource of the add-on configuration. + // +required + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Resource string `json:"resource"` +} + +// ConfigReferent represents the namespace and name for an add-on configuration. +type ConfigReferent struct { + // namespace of the add-on configuration. + // If this field is not set, the configuration is in the cluster scope. + // +optional + Namespace string `json:"namespace,omitempty"` + + // name of the add-on configuration. + // +required + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Name string `json:"name"` +} + +// ConfigSpecHash represents the namespace,name and spec hash for an add-on configuration. +type ConfigSpecHash struct { + // namespace and name for an add-on configuration. + ConfigReferent `json:",inline"` + + // spec hash for an add-on configuration. + SpecHash string `json:"specHash"` +} + +// InstallStrategy represents that related ManagedClusterAddOns should be installed +// on certain clusters. +type InstallStrategy struct { + // Type is the type of the install strategy, it can be: + // - Manual: no automatic install + // - Placements: install to clusters selected by placements. + // +kubebuilder:validation:Enum=Manual;Placements + // +kubebuilder:default:=Manual + // +optional + Type string `json:"type"` + // Placements is a list of placement references honored when install strategy type is + // Placements. All clusters selected by these placements will install the addon + // If one cluster belongs to multiple placements, it will only apply the strategy defined + // later in the order. That is to say, The latter strategy overrides the previous one. + // +optional + // +listType=map + // +listMapKey=namespace + // +listMapKey=name + Placements []PlacementStrategy `json:"placements,omitempty"` +} + +const ( + // AddonInstallStrategyManual is the addon install strategy representing no automatic addon installation + AddonInstallStrategyManual string = "Manual" + // AddonInstallStrategyPlacements is the addon install strategy representing the addon installation + // is based on placement decisions. + AddonInstallStrategyPlacements string = "Placements" +) + +type PlacementRef struct { + // Namespace is the namespace of the placement + // +required + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Namespace string `json:"namespace"` + // Name is the name of the placement + // +required + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Name string `json:"name"` +} + +type PlacementStrategy struct { + PlacementRef `json:",inline"` + // Configs is the configuration of managedClusterAddon during installation. + // User can override the configuration by updating the managedClusterAddon directly. + // +optional + Configs []AddOnConfig `json:"configs,omitempty"` + // The rollout strategy to apply addon configurations change. + // The rollout strategy only watches the addon configurations defined in ClusterManagementAddOn. + // +kubebuilder:default={type: All} + // +optional + RolloutStrategy clusterv1alpha1.RolloutStrategy `json:"rolloutStrategy,omitempty"` +} + +// ClusterManagementAddOnStatus represents the current status of cluster management add-on. +type ClusterManagementAddOnStatus struct { + // DefaultconfigReferences is a list of current add-on default configuration references. + // +optional + DefaultConfigReferences []DefaultConfigReference `json:"defaultconfigReferences,omitempty"` + // installProgression is a list of current add-on configuration references per placement. + // +optional + InstallProgressions []InstallProgression `json:"installProgressions,omitempty"` +} + +type InstallProgression struct { + PlacementRef `json:",inline"` + + // configReferences is a list of current add-on configuration references. + // +optional + ConfigReferences []InstallConfigReference `json:"configReferences,omitempty"` + + // conditions describe the state of the managed and monitored components for the operator. + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +// DefaultConfigReference is a reference to the current add-on configuration. +// This resource is used to record the configuration resource for the current add-on. +type DefaultConfigReference struct { + // This field is synced from ClusterManagementAddOn Configurations. + ConfigGroupResource `json:",inline"` + + // desiredConfig record the desired config spec hash. + DesiredConfig *ConfigSpecHash `json:"desiredConfig"` +} + +// InstallConfigReference is a reference to the current add-on configuration. +// This resource is used to record the configuration resource for the current add-on. +type InstallConfigReference struct { + // This field is synced from ClusterManagementAddOn Configurations. + ConfigGroupResource `json:",inline"` + + // desiredConfig record the desired config name and spec hash. + DesiredConfig *ConfigSpecHash `json:"desiredConfig"` + + // lastKnownGoodConfig records the last known good config spec hash. + // For fresh install or rollout with type UpdateAll or RollingUpdate, the + // lastKnownGoodConfig is the same as lastAppliedConfig. + // For rollout with type RollingUpdateWithCanary, the lastKnownGoodConfig + // is the last successfully applied config spec hash of the canary placement. + LastKnownGoodConfig *ConfigSpecHash `json:"lastKnownGoodConfig"` + + // lastAppliedConfig records the config spec hash when the all the corresponding + // ManagedClusterAddOn are applied successfully. + LastAppliedConfig *ConfigSpecHash `json:"lastAppliedConfig"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// ClusterManagementAddOnList is a collection of cluster management add-ons. +type ClusterManagementAddOnList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + // Items is a list of cluster management add-ons. + Items []ClusterManagementAddOn `json:"items"` +} + +const ( + // AddonLifecycleAnnotationKey is an annotation key on ClusterManagementAddon to indicate the installation + // and upgrade of addon should be handled by the general addon manager or addon itself. The valid values are + // addon-manager and self. If the annotation is not set, addon lifecycle is handled by addon itself. + AddonLifecycleAnnotationKey = "addon.open-cluster-management.io/lifecycle" + // AddonLifecycleAddonManagerAnnotationValue is the value of annotation AddonLifecycleAnnotationKey indicating + // that the addon installation and upgrade is handled by the general addon manager. This should be set only + // when featuregate AddonManager on hub is enabled + AddonLifecycleAddonManagerAnnotationValue = "addon-manager" + // AddonLifecycleSelfManageAnnotationValue is the value of annotation AddonLifecycleAnnotationKey indicating + // that the addon installation and upgrade is handled the addon itself. The general addon manager will ignore + // addons with this annotation. + AddonLifecycleSelfManageAnnotationValue = "self" +) diff --git a/addon/v1beta1/types_managedclusteraddon.go b/addon/v1beta1/types_managedclusteraddon.go new file mode 100644 index 00000000..c68c57d6 --- /dev/null +++ b/addon/v1beta1/types_managedclusteraddon.go @@ -0,0 +1,445 @@ +// Copyright Contributors to the Open Cluster Management project +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope="Namespaced",shortName={"mca","mcas"} +// +kubebuilder:printcolumn:name="Available",type=string,JSONPath=`.status.conditions[?(@.type=="Available")].status` +// +kubebuilder:printcolumn:name="Degraded",type=string,JSONPath=`.status.conditions[?(@.type=="Degraded")].status` +// +kubebuilder:printcolumn:name="Progressing",type=string,JSONPath=`.status.conditions[?(@.type=="Progressing")].status` + +// ManagedClusterAddOn is the Custom Resource object which holds the current state +// of an add-on. This object is used by add-on operators to convey their state. +// This resource should be created in the ManagedCluster namespace. +type ManagedClusterAddOn struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + // spec holds configuration that could apply to any operator. + // +kubebuilder:validation:Required + // +required + Spec ManagedClusterAddOnSpec `json:"spec"` + + // status holds the information about the state of an operator. It is consistent with status information across + // the Kubernetes ecosystem. + // +optional + Status ManagedClusterAddOnStatus `json:"status"` +} + +// ManagedClusterAddOnSpec defines the install configuration of +// an addon agent on managed cluster. +type ManagedClusterAddOnSpec struct { + // configs is a list of add-on configurations. + // In scenario where the current add-on has its own configurations. + // An empty list means there are no default configurations for add-on. + // The default is an empty list + // +optional + Configs []AddOnConfig `json:"configs,omitempty"` +} + +// RegistrationType represents the type of registration configuration for the addon agent. +type RegistrationType string + +const ( + // KubeClient represents the registration type for addon agents that need to access + // the hub kube-apiserver using kubeClient. + KubeClient RegistrationType = "KubeClient" + + // CSR represents the registration type for addon agents that need to access non-kube endpoints + // on the hub cluster with client certificate authentication. + CSR RegistrationType = "CSR" +) + +// RegistrationConfig defines the configuration for the addon agent to register to the hub cluster. +type RegistrationConfig struct { + // type specifies the type of registration configuration. + // +kubebuilder:validation:Enum=KubeClient;CSR + // +required + Type RegistrationType `json:"type,omitempty"` + + // kubeClient holds the configuration for KubeClient type registration. + // It should be set when type is "KubeClient". + // +optional + KubeClient *KubeClientConfig `json:"kubeClient,omitempty"` + + // csr holds the configuration for CSR type registration. + // It should be set when type is "CSR". + // +optional + CSR *CSRConfig `json:"csr,omitempty"` +} + +type KubeClientConfig struct { + // subject is the user subject of the addon agent to be registered to the hub. + // +optional + Subject Subject `json:"subject,omitempty"` +} + +type CSRConfig struct { + // signerName is the name of signer that addon agent will use to create csr. + // +required + // +kubebuilder:validation:MaxLength=571 + // +kubebuilder:validation:MinLength=5 + // +kubebuilder:validation:Pattern=^([a-z0-9][a-z0-9-]*[a-z0-9]\.)+[a-z]+\/[a-z0-9-\.]+$ + SignerName string `json:"signerName"` + + // subject is the user subject of the addon agent to be registered to the hub. + // +optional + Subject Subject `json:"subject,omitempty"` +} + +type AddOnConfig struct { + // group and resource of add-on configuration. + ConfigGroupResource `json:",inline"` + + // name and namespace of add-on configuration. + ConfigReferent `json:",inline"` +} + +// subject is the user subject of the addon agent to be registered to the hub. +// If it is not set, the addon agent will have the default subject +// +// "subject": { +// "user": "system:open-cluster-management:cluster:{clusterName}:addon:{addonName}:agent:{agentName}", +// "groups: ["system:open-cluster-management:cluster:{clusterName}:addon:{addonName}", +// "system:open-cluster-management:addon:{addonName}", "system:authenticated"] +// } +type Subject struct { + // user is the user name of the addon agent. + User string `json:"user"` + + // groups is the user group of the addon agent. + // +optional + Groups []string `json:"groups,omitempty"` + + // organizationUnit is the ou of the addon agent + // +optional + OrganizationUnits []string `json:"organizationUnit,omitempty"` +} + +// ManagedClusterAddOnStatus provides information about the status of the operator. +// +k8s:deepcopy-gen=true +type ManagedClusterAddOnStatus struct { + // conditions describe the state of the managed and monitored components for the operator. + // +patchMergeKey=type + // +patchStrategy=merge + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` + + // relatedObjects is a list of objects that are "interesting" or related to this operator. Common uses are: + // 1. the detailed resource driving the operator + // 2. operator namespaces + // 3. operand namespaces + // 4. related ClusterManagementAddon resource + // +optional + RelatedObjects []ObjectReference `json:"relatedObjects,omitempty"` + + // addOnMeta is a reference to the metadata information for the add-on. + // This should be same as the addOnMeta for the corresponding ClusterManagementAddOn resource. + // +optional + AddOnMeta AddOnMeta `json:"addOnMeta,omitempty"` + + // SupportedConfigs is a list of configuration types that are allowed to override the add-on configurations defined + // in ClusterManagementAddOn spec. + // The default is an empty list, which means the add-on configurations can not be overridden. + // +optional + // +listType=map + // +listMapKey=group + // +listMapKey=resource + SupportedConfigs []ConfigGroupResource `json:"supportedConfigs,omitempty"` + + // configReferences is a list of current add-on configuration references. + // This will be overridden by the clustermanagementaddon configuration references. + // +optional + ConfigReferences []ConfigReference `json:"configReferences,omitempty"` + + // namespace is the namespace on the managedcluster to put registration secret or lease for the addon. It is + // required when registration is set or healthcheck mode is Lease. + // +optional + Namespace string `json:"namespace,omitempty"` + + // registrations is the configurations for the addon agent to register to hub. It should be set by each addon controller + // on hub to define how the addon agent on managedcluster is registered. With the registration defined, + // The addon agent can access to kube apiserver with kube style API or other endpoints on hub cluster with client + // certificate authentication. A csr will be created per registration configuration. If more than one + // registrationConfig is defined, a csr will be created for each registration configuration. It is not allowed that + // multiple registrationConfigs have the same signer name. After the csr is approved on the hub cluster, the klusterlet + // agent will create a secret in the installNamespace for the registrationConfig. If the signerName is + // "kubernetes.io/kube-apiserver-client", the secret name will be "{addon name}-hub-kubeconfig" whose contents includes + // key/cert and kubeconfig. Otherwise, the secret name will be "{addon name}-{signer name}-client-cert" whose contents includes key/cert. + // +optional + Registrations []RegistrationConfig `json:"registrations,omitempty"` + + // healthCheck indicates how to check the healthiness status of the current addon. It should be + // set by each addon implementation, by default, the lease mode will be used. + // +optional + HealthCheck HealthCheck `json:"healthCheck,omitempty"` +} + +// ObjectReference contains enough information to let you inspect or modify the referred object. +type ObjectReference struct { + // group of the referent. + // +kubebuilder:validation:Required + // +required + Group string `json:"group"` + // resource of the referent. + // +kubebuilder:validation:Required + // +required + Resource string `json:"resource"` + // namespace of the referent. + // +optional + Namespace string `json:"namespace,omitempty"` + // name of the referent. + // +kubebuilder:validation:Required + // +required + Name string `json:"name"` +} + +// ConfigReference is a reference to the current add-on configuration. +// This resource is used to locate the configuration resource for the current add-on. +type ConfigReference struct { + // This field is synced from ClusterManagementAddOn configGroupResource field. + ConfigGroupResource `json:",inline"` + + // lastObservedGeneration is the observed generation of the add-on configuration. + LastObservedGeneration int64 `json:"lastObservedGeneration"` + + // desiredConfig record the desired config spec hash. + // +optional + DesiredConfig *ConfigSpecHash `json:"desiredConfig"` + + // lastAppliedConfig record the config spec hash when the corresponding ManifestWork is applied successfully. + // +optional + LastAppliedConfig *ConfigSpecHash `json:"lastAppliedConfig"` +} + +// HealthCheckMode indicates the mode for the addon to check its healthiness status +// +kubebuilder:validation:Enum=Lease;Customized +type HealthCheckMode string + +const ( + // HealthCheckModeLease, the addon maintains a lease in its installation namespace with + // its status, the registration agent will check this lease to maintain the addon healthiness + // status. + HealthCheckModeLease HealthCheckMode = "Lease" + + // HealthCheckModeCustomized, the addon maintains its healthiness status by itself. + HealthCheckModeCustomized HealthCheckMode = "Customized" +) + +type HealthCheck struct { + // mode indicates which mode will be used to check the healthiness status of the addon. + // +optional + // +kubebuilder:default=Lease + Mode HealthCheckMode `json:"mode,omitempty"` +} + +// ManagedClusterAddOnList is a list of ManagedClusterAddOn resources. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type ManagedClusterAddOnList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ManagedClusterAddOn `json:"items"` +} + +const ( + // Label and annotation keys set on ManagedClusterAddon. + + // AddonLabelKey is the label key to set addon name. It is to set on the resources on the hub relating + // to an addon + AddonLabelKey = "open-cluster-management.io/addon-name" + + // DisableAddonAutomaticInstallationAnnotationKey is the annotation key for disabling the functionality of + // installing addon automatically. it should be set on ManagedClusterAddon resource only. + DisableAddonAutomaticInstallationAnnotationKey = "addon.open-cluster-management.io/disable-automatic-installation" + + // AddonNamespaceLabelKey is the label key to set namespace of ManagedClusterAddon. + AddonNamespaceLabelKey = "open-cluster-management.io/addon-namespace" + + // Label and annotation keys set on manifests of addon agent. + + // AddonPreDeleteHookAnnotationKey is the annotation key to identify that a resource manifest is used as pre-delete hook for an addon + // and should be created and deleted before the specified ManagedClusterAddon is deleted. + AddonPreDeleteHookAnnotationKey = "addon.open-cluster-management.io/addon-pre-delete" + + // HostingClusterNameAnnotationKey is the annotation key for indicating the hosting cluster name, it should be set + // on ManagedClusterAddon resource only. + HostingClusterNameAnnotationKey = "addon.open-cluster-management.io/hosting-cluster-name" + + // DeletionOrphanAnnotationKey is an annotation for the manifest of addon indicating that it will not be cleaned up + // after the addon is deleted. + DeletionOrphanAnnotationKey = "addon.open-cluster-management.io/deletion-orphan" + + // HostedManifestLocationAnnotationKey is the annotation key to identify where a resource manifest of addon agent + // with this annotation should be deployed in Hosted mode. + HostedManifestLocationAnnotationKey = "addon.open-cluster-management.io/hosted-manifest-location" + + // HostedManifestLocationManagedValue is a value of the annotation HostedManifestLocationAnnotationKey, + // indicates the manifest will be deployed on the managed cluster in Hosted mode, + // it is the default value of a manifest in Hosted mode. + HostedManifestLocationManagedValue = "managed" + // HostedManifestLocationHostingValue is a value of the annotation HostedManifestLocationAnnotationKey, + // indicates the manifest will be deployed on the hosting cluster in Hosted mode. + HostedManifestLocationHostingValue = "hosting" + // HostedManifestLocationNoneValue is a value of the annotation HostedManifestLocationAnnotationKey, + // indicates the manifest will not be deployed in Hosted mode. + HostedManifestLocationNoneValue = "none" + + // Finalizers on the managedClusterAddon. + + // AddonPreDeleteHookFinalizer is the finalizer for an addon which has deployed hook objects. + AddonPreDeleteHookFinalizer = "addon.open-cluster-management.io/addon-pre-delete" + // AddonHostingPreDeleteHookFinalizer is the finalizer for an addon which has deployed hook objects + // on hosting cluster. + AddonHostingPreDeleteHookFinalizer = "addon.open-cluster-management.io/hosting-addon-pre-delete" + // AddonHostingManifestFinalizer is the finalizer for an addon which has deployed manifests on the external + // hosting cluster in Hosted mode. + AddonHostingManifestFinalizer = "addon.open-cluster-management.io/hosting-manifests-cleanup" +) + +// addon status condition types +const ( + // ManagedClusterAddOnConditionAvailable represents that the addon agent is running on the managed cluster + ManagedClusterAddOnConditionAvailable string = "Available" + + // ManagedClusterAddOnConditionDegraded represents that the addon agent is providing degraded service on + // the managed cluster. + ManagedClusterAddOnConditionDegraded string = "Degraded" + + // ManagedClusterAddOnConditionConfigured represents that the addon agent is configured with its configuration + ManagedClusterAddOnConditionConfigured string = "Configured" + + // ManagedClusterAddOnConditionProgressing represents that the addon agent is applying configurations. + ManagedClusterAddOnConditionProgressing string = "Progressing" + + // ManagedClusterAddOnManifestApplied is a condition type representing whether the manifest of an addon is + // applied correctly. + ManagedClusterAddOnManifestApplied = "ManifestApplied" + + // ManagedClusterAddOnHookManifestCompleted is a condition type representing whether the addon hook is completed. + ManagedClusterAddOnHookManifestCompleted = "HookManifestCompleted" + + // ManagedClusterAddOnHostingManifestApplied is a condition type representing whether the manifest of an addon + // is applied on the hosting cluster correctly. + ManagedClusterAddOnHostingManifestApplied = "HostingManifestApplied" + + // ManagedClusterAddOnHostingClusterValidity is a condition type representing whether the hosting cluster is + // valid in Hosted mode. + ManagedClusterAddOnHostingClusterValidity = "HostingClusterValidity" + + // ManagedClusterAddOnRegistrationApplied is a condition type representing whether the registration of + // the addon agent is configured. + ManagedClusterAddOnRegistrationApplied = "RegistrationApplied" +) + +// the reasons of condition ManagedClusterAddOnConditionAvailable +const ( + // AddonAvailableReasonWorkNotFound is the reason of condition Available indicating the addon manifestWorks + // are not found. + AddonAvailableReasonWorkNotFound = "WorkNotFound" + + // AddonAvailableReasonWorkApplyFailed is the reason of condition Available indicating the addon manifestWorks + // are failed to apply. + AddonAvailableReasonWorkApplyFailed = "WorkApplyFailed" + + // AddonAvailableReasonWorkNotApply is the reason of condition Available indicating the addon manifestWorks + // are not applied. + AddonAvailableReasonWorkNotApply = "WorkNotApplied" + + // AddonAvailableReasonWorkApply is the reason of condition Available indicating the addon manifestWorks + // are applied. + AddonAvailableReasonWorkApply = "WorkApplied" + + // AddonAvailableReasonNoProbeResult is the reason of condition Available indicating no probe result found in + // the manifestWorks for the health check. + AddonAvailableReasonNoProbeResult = "NoProbeResult" + + // AddonAvailableReasonProbeUnavailable is the reason of condition Available indicating the probe result found + // does not meet the health check. + AddonAvailableReasonProbeUnavailable = "ProbeUnavailable" + + // AddonAvailableReasonProbeAvailable is the reason of condition Available indicating the probe result found + // meets the health check. + AddonAvailableReasonProbeAvailable = "ProbeAvailable" + + // AddonAvailableReasonLeaseUpdateStopped is the reason if condition Available indicating the lease stops updating + // during health check. + AddonAvailableReasonLeaseUpdateStopped = "ManagedClusterAddOnLeaseUpdateStopped" + + // AddonAvailableReasonLeaseLeaseNotFound is the reason if condition Available indicating the lease is not found + // during health check. + AddonAvailableReasonLeaseLeaseNotFound = "ManagedClusterAddOnLeaseNotFound" + + // AddonAvailableReasonLeaseLeaseUpdated is the reason if condition Available indicating the lease is updated + // during health check. + AddonAvailableReasonLeaseLeaseUpdated = "ManagedClusterAddOnLeaseUpdated" +) + +// the reasons of condition ManagedClusterAddOnManifestApplied +const ( + // AddonManifestAppliedReasonWorkApplyFailed is the reason of condition AddonManifestApplied indicating + // the failure of apply manifestWork of the manifests. + AddonManifestAppliedReasonWorkApplyFailed = "ManifestWorkApplyFailed" + + // AddonManifestAppliedReasonManifestsApplied is the reason of condition AddonManifestApplied indicating + // the manifests is applied on the managedCluster. + AddonManifestAppliedReasonManifestsApplied = "AddonManifestApplied" + + // AddonManifestAppliedReasonManifestsApplyFailed is the reason of condition AddonManifestApplied indicating + // the failure to apply manifests on the managedCluster. + AddonManifestAppliedReasonManifestsApplyFailed = "AddonManifestAppliedFailed" +) + +// the reasons of condition ManagedClusterAddOnHostingClusterValidity +const ( + // HostingClusterValidityReasonValid is the reason of condition HostingClusterValidity indicating the hosting + // cluster is valid. + HostingClusterValidityReasonValid = "HostingClusterValid" + + // HostingClusterValidityReasonInvalid is the reason of condition HostingClusterValidity indicating the hosting + // cluster is invalid. + HostingClusterValidityReasonInvalid = "HostingClusterInvalid" +) + +// the reason of condition ManagedClusterAddOnConditionProgressing +const ( + // ProgressingReasonProgressing is the reason of condition Progressing indicating the addon configuration is + // applying. + ProgressingReasonProgressing = "Progressing" + + // ProgressingReasonCompleted is the reason of condition Progressing indicating the addon configuration is + // applied successfully. + ProgressingReasonCompleted = "Completed" + + // ProgressingReasonFailed is the reason of condition Progressing indicating the addon configuration + // failed to apply. + ProgressingReasonFailed = "Failed" + + // ProgressingReasonWaitingForCanary is the reason of condition Progressing indicating the addon configuration + // upgrade is pending and waiting for canary is done. + ProgressingReasonWaitingForCanary = "WaitingForCanary" + + // ProgressingReasonConfigurationUnsupported is the reason of condition Progressing indicating the addon configuration + // is not supported. + ProgressingReasonConfigurationUnsupported = "ConfigurationUnsupported" +) + +// the reasons of condition ManagedClusterAddOnRegistrationApplied +const ( + // RegistrationAppliedNilRegistration is the reason of condition RegistrationApplied indicating that there is no + // registration option. + RegistrationAppliedNilRegistration = "NilRegistration" + + // RegistrationAppliedSetPermissionFailed is the reason of condition RegistrationApplied indicating that it is + // failed to set up rbac for the addon agent. + RegistrationAppliedSetPermissionFailed = "SetPermissionFailed" + + // RegistrationAppliedSetPermissionApplied is the reason of condition RegistrationApplied indicating that it is + // successful to set up rbac for the addon agent. + RegistrationAppliedSetPermissionApplied = "SetPermissionApplied" +) diff --git a/addon/v1beta1/zz_generated.deepcopy.go b/addon/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000..d75375bb --- /dev/null +++ b/addon/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,632 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Copyright Contributors to the Open Cluster Management project +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddOnConfig) DeepCopyInto(out *AddOnConfig) { + *out = *in + out.ConfigGroupResource = in.ConfigGroupResource + out.ConfigReferent = in.ConfigReferent + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddOnConfig. +func (in *AddOnConfig) DeepCopy() *AddOnConfig { + if in == nil { + return nil + } + out := new(AddOnConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AddOnMeta) DeepCopyInto(out *AddOnMeta) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddOnMeta. +func (in *AddOnMeta) DeepCopy() *AddOnMeta { + if in == nil { + return nil + } + out := new(AddOnMeta) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CSRConfig) DeepCopyInto(out *CSRConfig) { + *out = *in + in.Subject.DeepCopyInto(&out.Subject) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CSRConfig. +func (in *CSRConfig) DeepCopy() *CSRConfig { + if in == nil { + return nil + } + out := new(CSRConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterManagementAddOn) DeepCopyInto(out *ClusterManagementAddOn) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterManagementAddOn. +func (in *ClusterManagementAddOn) DeepCopy() *ClusterManagementAddOn { + if in == nil { + return nil + } + out := new(ClusterManagementAddOn) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterManagementAddOn) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterManagementAddOnList) DeepCopyInto(out *ClusterManagementAddOnList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterManagementAddOn, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterManagementAddOnList. +func (in *ClusterManagementAddOnList) DeepCopy() *ClusterManagementAddOnList { + if in == nil { + return nil + } + out := new(ClusterManagementAddOnList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterManagementAddOnList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterManagementAddOnSpec) DeepCopyInto(out *ClusterManagementAddOnSpec) { + *out = *in + out.AddOnMeta = in.AddOnMeta + if in.DefaultConfigs != nil { + in, out := &in.DefaultConfigs, &out.DefaultConfigs + *out = make([]AddOnConfig, len(*in)) + copy(*out, *in) + } + in.InstallStrategy.DeepCopyInto(&out.InstallStrategy) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterManagementAddOnSpec. +func (in *ClusterManagementAddOnSpec) DeepCopy() *ClusterManagementAddOnSpec { + if in == nil { + return nil + } + out := new(ClusterManagementAddOnSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterManagementAddOnStatus) DeepCopyInto(out *ClusterManagementAddOnStatus) { + *out = *in + if in.DefaultConfigReferences != nil { + in, out := &in.DefaultConfigReferences, &out.DefaultConfigReferences + *out = make([]DefaultConfigReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.InstallProgressions != nil { + in, out := &in.InstallProgressions, &out.InstallProgressions + *out = make([]InstallProgression, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterManagementAddOnStatus. +func (in *ClusterManagementAddOnStatus) DeepCopy() *ClusterManagementAddOnStatus { + if in == nil { + return nil + } + out := new(ClusterManagementAddOnStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigGroupResource) DeepCopyInto(out *ConfigGroupResource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigGroupResource. +func (in *ConfigGroupResource) DeepCopy() *ConfigGroupResource { + if in == nil { + return nil + } + out := new(ConfigGroupResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigReference) DeepCopyInto(out *ConfigReference) { + *out = *in + out.ConfigGroupResource = in.ConfigGroupResource + if in.DesiredConfig != nil { + in, out := &in.DesiredConfig, &out.DesiredConfig + *out = new(ConfigSpecHash) + **out = **in + } + if in.LastAppliedConfig != nil { + in, out := &in.LastAppliedConfig, &out.LastAppliedConfig + *out = new(ConfigSpecHash) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigReference. +func (in *ConfigReference) DeepCopy() *ConfigReference { + if in == nil { + return nil + } + out := new(ConfigReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigReferent) DeepCopyInto(out *ConfigReferent) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigReferent. +func (in *ConfigReferent) DeepCopy() *ConfigReferent { + if in == nil { + return nil + } + out := new(ConfigReferent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigSpecHash) DeepCopyInto(out *ConfigSpecHash) { + *out = *in + out.ConfigReferent = in.ConfigReferent + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigSpecHash. +func (in *ConfigSpecHash) DeepCopy() *ConfigSpecHash { + if in == nil { + return nil + } + out := new(ConfigSpecHash) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DefaultConfigReference) DeepCopyInto(out *DefaultConfigReference) { + *out = *in + out.ConfigGroupResource = in.ConfigGroupResource + if in.DesiredConfig != nil { + in, out := &in.DesiredConfig, &out.DesiredConfig + *out = new(ConfigSpecHash) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultConfigReference. +func (in *DefaultConfigReference) DeepCopy() *DefaultConfigReference { + if in == nil { + return nil + } + out := new(DefaultConfigReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheck) DeepCopyInto(out *HealthCheck) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheck. +func (in *HealthCheck) DeepCopy() *HealthCheck { + if in == nil { + return nil + } + out := new(HealthCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstallConfigReference) DeepCopyInto(out *InstallConfigReference) { + *out = *in + out.ConfigGroupResource = in.ConfigGroupResource + if in.DesiredConfig != nil { + in, out := &in.DesiredConfig, &out.DesiredConfig + *out = new(ConfigSpecHash) + **out = **in + } + if in.LastKnownGoodConfig != nil { + in, out := &in.LastKnownGoodConfig, &out.LastKnownGoodConfig + *out = new(ConfigSpecHash) + **out = **in + } + if in.LastAppliedConfig != nil { + in, out := &in.LastAppliedConfig, &out.LastAppliedConfig + *out = new(ConfigSpecHash) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallConfigReference. +func (in *InstallConfigReference) DeepCopy() *InstallConfigReference { + if in == nil { + return nil + } + out := new(InstallConfigReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstallProgression) DeepCopyInto(out *InstallProgression) { + *out = *in + out.PlacementRef = in.PlacementRef + if in.ConfigReferences != nil { + in, out := &in.ConfigReferences, &out.ConfigReferences + *out = make([]InstallConfigReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallProgression. +func (in *InstallProgression) DeepCopy() *InstallProgression { + if in == nil { + return nil + } + out := new(InstallProgression) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstallStrategy) DeepCopyInto(out *InstallStrategy) { + *out = *in + if in.Placements != nil { + in, out := &in.Placements, &out.Placements + *out = make([]PlacementStrategy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstallStrategy. +func (in *InstallStrategy) DeepCopy() *InstallStrategy { + if in == nil { + return nil + } + out := new(InstallStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeClientConfig) DeepCopyInto(out *KubeClientConfig) { + *out = *in + in.Subject.DeepCopyInto(&out.Subject) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeClientConfig. +func (in *KubeClientConfig) DeepCopy() *KubeClientConfig { + if in == nil { + return nil + } + out := new(KubeClientConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedClusterAddOn) DeepCopyInto(out *ManagedClusterAddOn) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedClusterAddOn. +func (in *ManagedClusterAddOn) DeepCopy() *ManagedClusterAddOn { + if in == nil { + return nil + } + out := new(ManagedClusterAddOn) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedClusterAddOn) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedClusterAddOnList) DeepCopyInto(out *ManagedClusterAddOnList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ManagedClusterAddOn, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedClusterAddOnList. +func (in *ManagedClusterAddOnList) DeepCopy() *ManagedClusterAddOnList { + if in == nil { + return nil + } + out := new(ManagedClusterAddOnList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedClusterAddOnList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedClusterAddOnSpec) DeepCopyInto(out *ManagedClusterAddOnSpec) { + *out = *in + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make([]AddOnConfig, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedClusterAddOnSpec. +func (in *ManagedClusterAddOnSpec) DeepCopy() *ManagedClusterAddOnSpec { + if in == nil { + return nil + } + out := new(ManagedClusterAddOnSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedClusterAddOnStatus) DeepCopyInto(out *ManagedClusterAddOnStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.RelatedObjects != nil { + in, out := &in.RelatedObjects, &out.RelatedObjects + *out = make([]ObjectReference, len(*in)) + copy(*out, *in) + } + out.AddOnMeta = in.AddOnMeta + if in.SupportedConfigs != nil { + in, out := &in.SupportedConfigs, &out.SupportedConfigs + *out = make([]ConfigGroupResource, len(*in)) + copy(*out, *in) + } + if in.ConfigReferences != nil { + in, out := &in.ConfigReferences, &out.ConfigReferences + *out = make([]ConfigReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Registrations != nil { + in, out := &in.Registrations, &out.Registrations + *out = make([]RegistrationConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.HealthCheck = in.HealthCheck + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedClusterAddOnStatus. +func (in *ManagedClusterAddOnStatus) DeepCopy() *ManagedClusterAddOnStatus { + if in == nil { + return nil + } + out := new(ManagedClusterAddOnStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectReference) DeepCopyInto(out *ObjectReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectReference. +func (in *ObjectReference) DeepCopy() *ObjectReference { + if in == nil { + return nil + } + out := new(ObjectReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PlacementRef) DeepCopyInto(out *PlacementRef) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementRef. +func (in *PlacementRef) DeepCopy() *PlacementRef { + if in == nil { + return nil + } + out := new(PlacementRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PlacementStrategy) DeepCopyInto(out *PlacementStrategy) { + *out = *in + out.PlacementRef = in.PlacementRef + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make([]AddOnConfig, len(*in)) + copy(*out, *in) + } + in.RolloutStrategy.DeepCopyInto(&out.RolloutStrategy) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementStrategy. +func (in *PlacementStrategy) DeepCopy() *PlacementStrategy { + if in == nil { + return nil + } + out := new(PlacementStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegistrationConfig) DeepCopyInto(out *RegistrationConfig) { + *out = *in + if in.KubeClient != nil { + in, out := &in.KubeClient, &out.KubeClient + *out = new(KubeClientConfig) + (*in).DeepCopyInto(*out) + } + if in.CSR != nil { + in, out := &in.CSR, &out.CSR + *out = new(CSRConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistrationConfig. +func (in *RegistrationConfig) DeepCopy() *RegistrationConfig { + if in == nil { + return nil + } + out := new(RegistrationConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Subject) DeepCopyInto(out *Subject) { + *out = *in + if in.Groups != nil { + in, out := &in.Groups, &out.Groups + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.OrganizationUnits != nil { + in, out := &in.OrganizationUnits, &out.OrganizationUnits + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subject. +func (in *Subject) DeepCopy() *Subject { + if in == nil { + return nil + } + out := new(Subject) + in.DeepCopyInto(out) + return out +} diff --git a/client/addon/clientset/versioned/clientset.go b/client/addon/clientset/versioned/clientset.go index 2c0bde11..bbb2f05d 100644 --- a/client/addon/clientset/versioned/clientset.go +++ b/client/addon/clientset/versioned/clientset.go @@ -11,17 +11,20 @@ import ( rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" addonv1alpha1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1alpha1" + addonv1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1" ) type Interface interface { Discovery() discovery.DiscoveryInterface AddonV1alpha1() addonv1alpha1.AddonV1alpha1Interface + AddonV1beta1() addonv1beta1.AddonV1beta1Interface } // Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient addonV1alpha1 *addonv1alpha1.AddonV1alpha1Client + addonV1beta1 *addonv1beta1.AddonV1beta1Client } // AddonV1alpha1 retrieves the AddonV1alpha1Client @@ -29,6 +32,11 @@ func (c *Clientset) AddonV1alpha1() addonv1alpha1.AddonV1alpha1Interface { return c.addonV1alpha1 } +// AddonV1beta1 retrieves the AddonV1beta1Client +func (c *Clientset) AddonV1beta1() addonv1beta1.AddonV1beta1Interface { + return c.addonV1beta1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -77,6 +85,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.addonV1beta1, err = addonv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) if err != nil { @@ -99,6 +111,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.addonV1alpha1 = addonv1alpha1.New(c) + cs.addonV1beta1 = addonv1beta1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/client/addon/clientset/versioned/fake/clientset_generated.go b/client/addon/clientset/versioned/fake/clientset_generated.go index 2821011e..e8642d3a 100644 --- a/client/addon/clientset/versioned/fake/clientset_generated.go +++ b/client/addon/clientset/versioned/fake/clientset_generated.go @@ -13,6 +13,8 @@ import ( clientset "open-cluster-management.io/api/client/addon/clientset/versioned" addonv1alpha1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1alpha1" fakeaddonv1alpha1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1alpha1/fake" + addonv1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1" + fakeaddonv1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1/fake" ) // NewSimpleClientset returns a clientset that will respond with the provided objects. @@ -77,3 +79,8 @@ var ( func (c *Clientset) AddonV1alpha1() addonv1alpha1.AddonV1alpha1Interface { return &fakeaddonv1alpha1.FakeAddonV1alpha1{Fake: &c.Fake} } + +// AddonV1beta1 retrieves the AddonV1beta1Client +func (c *Clientset) AddonV1beta1() addonv1beta1.AddonV1beta1Interface { + return &fakeaddonv1beta1.FakeAddonV1beta1{Fake: &c.Fake} +} diff --git a/client/addon/clientset/versioned/fake/register.go b/client/addon/clientset/versioned/fake/register.go index d6eb2efc..43f25df6 100644 --- a/client/addon/clientset/versioned/fake/register.go +++ b/client/addon/clientset/versioned/fake/register.go @@ -10,6 +10,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" ) var scheme = runtime.NewScheme() @@ -17,6 +18,7 @@ var codecs = serializer.NewCodecFactory(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ addonv1alpha1.AddToScheme, + addonv1beta1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/client/addon/clientset/versioned/scheme/register.go b/client/addon/clientset/versioned/scheme/register.go index abd91cfb..c1b768d6 100644 --- a/client/addon/clientset/versioned/scheme/register.go +++ b/client/addon/clientset/versioned/scheme/register.go @@ -10,6 +10,7 @@ import ( serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" ) var Scheme = runtime.NewScheme() @@ -17,6 +18,7 @@ var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ addonv1alpha1.AddToScheme, + addonv1beta1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/addon_client.go b/client/addon/clientset/versioned/typed/addon/v1beta1/addon_client.go new file mode 100644 index 00000000..4f92afc5 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/addon_client.go @@ -0,0 +1,91 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + http "net/http" + + rest "k8s.io/client-go/rest" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" + scheme "open-cluster-management.io/api/client/addon/clientset/versioned/scheme" +) + +type AddonV1beta1Interface interface { + RESTClient() rest.Interface + ClusterManagementAddOnsGetter + ManagedClusterAddOnsGetter +} + +// AddonV1beta1Client is used to interact with features provided by the addon.open-cluster-management.io group. +type AddonV1beta1Client struct { + restClient rest.Interface +} + +func (c *AddonV1beta1Client) ClusterManagementAddOns() ClusterManagementAddOnInterface { + return newClusterManagementAddOns(c) +} + +func (c *AddonV1beta1Client) ManagedClusterAddOns(namespace string) ManagedClusterAddOnInterface { + return newManagedClusterAddOns(c, namespace) +} + +// NewForConfig creates a new AddonV1beta1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*AddonV1beta1Client, error) { + config := *c + setConfigDefaults(&config) + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new AddonV1beta1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*AddonV1beta1Client, error) { + config := *c + setConfigDefaults(&config) + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &AddonV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new AddonV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *AddonV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new AddonV1beta1Client for the given RESTClient. +func New(c rest.Interface) *AddonV1beta1Client { + return &AddonV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) { + gv := addonv1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *AddonV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/clustermanagementaddon.go b/client/addon/clientset/versioned/typed/addon/v1beta1/clustermanagementaddon.go new file mode 100644 index 00000000..9bc39e24 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/clustermanagementaddon.go @@ -0,0 +1,55 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + context "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" + scheme "open-cluster-management.io/api/client/addon/clientset/versioned/scheme" +) + +// ClusterManagementAddOnsGetter has a method to return a ClusterManagementAddOnInterface. +// A group's client should implement this interface. +type ClusterManagementAddOnsGetter interface { + ClusterManagementAddOns() ClusterManagementAddOnInterface +} + +// ClusterManagementAddOnInterface has methods to work with ClusterManagementAddOn resources. +type ClusterManagementAddOnInterface interface { + Create(ctx context.Context, clusterManagementAddOn *addonv1beta1.ClusterManagementAddOn, opts v1.CreateOptions) (*addonv1beta1.ClusterManagementAddOn, error) + Update(ctx context.Context, clusterManagementAddOn *addonv1beta1.ClusterManagementAddOn, opts v1.UpdateOptions) (*addonv1beta1.ClusterManagementAddOn, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, clusterManagementAddOn *addonv1beta1.ClusterManagementAddOn, opts v1.UpdateOptions) (*addonv1beta1.ClusterManagementAddOn, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*addonv1beta1.ClusterManagementAddOn, error) + List(ctx context.Context, opts v1.ListOptions) (*addonv1beta1.ClusterManagementAddOnList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *addonv1beta1.ClusterManagementAddOn, err error) + ClusterManagementAddOnExpansion +} + +// clusterManagementAddOns implements ClusterManagementAddOnInterface +type clusterManagementAddOns struct { + *gentype.ClientWithList[*addonv1beta1.ClusterManagementAddOn, *addonv1beta1.ClusterManagementAddOnList] +} + +// newClusterManagementAddOns returns a ClusterManagementAddOns +func newClusterManagementAddOns(c *AddonV1beta1Client) *clusterManagementAddOns { + return &clusterManagementAddOns{ + gentype.NewClientWithList[*addonv1beta1.ClusterManagementAddOn, *addonv1beta1.ClusterManagementAddOnList]( + "clustermanagementaddons", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *addonv1beta1.ClusterManagementAddOn { return &addonv1beta1.ClusterManagementAddOn{} }, + func() *addonv1beta1.ClusterManagementAddOnList { return &addonv1beta1.ClusterManagementAddOnList{} }, + ), + } +} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/doc.go b/client/addon/clientset/versioned/typed/addon/v1beta1/doc.go new file mode 100644 index 00000000..0ff94582 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/doc.go @@ -0,0 +1,5 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/fake/doc.go b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/doc.go new file mode 100644 index 00000000..97b0a07e --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/doc.go @@ -0,0 +1,5 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_addon_client.go b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_addon_client.go new file mode 100644 index 00000000..0cddecc5 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_addon_client.go @@ -0,0 +1,29 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1" +) + +type FakeAddonV1beta1 struct { + *testing.Fake +} + +func (c *FakeAddonV1beta1) ClusterManagementAddOns() v1beta1.ClusterManagementAddOnInterface { + return newFakeClusterManagementAddOns(c) +} + +func (c *FakeAddonV1beta1) ManagedClusterAddOns(namespace string) v1beta1.ManagedClusterAddOnInterface { + return newFakeManagedClusterAddOns(c, namespace) +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeAddonV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_clustermanagementaddon.go b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_clustermanagementaddon.go new file mode 100644 index 00000000..de347163 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_clustermanagementaddon.go @@ -0,0 +1,37 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + gentype "k8s.io/client-go/gentype" + v1beta1 "open-cluster-management.io/api/addon/v1beta1" + addonv1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1" +) + +// fakeClusterManagementAddOns implements ClusterManagementAddOnInterface +type fakeClusterManagementAddOns struct { + *gentype.FakeClientWithList[*v1beta1.ClusterManagementAddOn, *v1beta1.ClusterManagementAddOnList] + Fake *FakeAddonV1beta1 +} + +func newFakeClusterManagementAddOns(fake *FakeAddonV1beta1) addonv1beta1.ClusterManagementAddOnInterface { + return &fakeClusterManagementAddOns{ + gentype.NewFakeClientWithList[*v1beta1.ClusterManagementAddOn, *v1beta1.ClusterManagementAddOnList]( + fake.Fake, + "", + v1beta1.SchemeGroupVersion.WithResource("clustermanagementaddons"), + v1beta1.SchemeGroupVersion.WithKind("ClusterManagementAddOn"), + func() *v1beta1.ClusterManagementAddOn { return &v1beta1.ClusterManagementAddOn{} }, + func() *v1beta1.ClusterManagementAddOnList { return &v1beta1.ClusterManagementAddOnList{} }, + func(dst, src *v1beta1.ClusterManagementAddOnList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta1.ClusterManagementAddOnList) []*v1beta1.ClusterManagementAddOn { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1beta1.ClusterManagementAddOnList, items []*v1beta1.ClusterManagementAddOn) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_managedclusteraddon.go b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_managedclusteraddon.go new file mode 100644 index 00000000..6fdea788 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/fake/fake_managedclusteraddon.go @@ -0,0 +1,37 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + gentype "k8s.io/client-go/gentype" + v1beta1 "open-cluster-management.io/api/addon/v1beta1" + addonv1beta1 "open-cluster-management.io/api/client/addon/clientset/versioned/typed/addon/v1beta1" +) + +// fakeManagedClusterAddOns implements ManagedClusterAddOnInterface +type fakeManagedClusterAddOns struct { + *gentype.FakeClientWithList[*v1beta1.ManagedClusterAddOn, *v1beta1.ManagedClusterAddOnList] + Fake *FakeAddonV1beta1 +} + +func newFakeManagedClusterAddOns(fake *FakeAddonV1beta1, namespace string) addonv1beta1.ManagedClusterAddOnInterface { + return &fakeManagedClusterAddOns{ + gentype.NewFakeClientWithList[*v1beta1.ManagedClusterAddOn, *v1beta1.ManagedClusterAddOnList]( + fake.Fake, + namespace, + v1beta1.SchemeGroupVersion.WithResource("managedclusteraddons"), + v1beta1.SchemeGroupVersion.WithKind("ManagedClusterAddOn"), + func() *v1beta1.ManagedClusterAddOn { return &v1beta1.ManagedClusterAddOn{} }, + func() *v1beta1.ManagedClusterAddOnList { return &v1beta1.ManagedClusterAddOnList{} }, + func(dst, src *v1beta1.ManagedClusterAddOnList) { dst.ListMeta = src.ListMeta }, + func(list *v1beta1.ManagedClusterAddOnList) []*v1beta1.ManagedClusterAddOn { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1beta1.ManagedClusterAddOnList, items []*v1beta1.ManagedClusterAddOn) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/generated_expansion.go b/client/addon/clientset/versioned/typed/addon/v1beta1/generated_expansion.go new file mode 100644 index 00000000..79fe4e3c --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/generated_expansion.go @@ -0,0 +1,8 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type ClusterManagementAddOnExpansion interface{} + +type ManagedClusterAddOnExpansion interface{} diff --git a/client/addon/clientset/versioned/typed/addon/v1beta1/managedclusteraddon.go b/client/addon/clientset/versioned/typed/addon/v1beta1/managedclusteraddon.go new file mode 100644 index 00000000..3da6a3e7 --- /dev/null +++ b/client/addon/clientset/versioned/typed/addon/v1beta1/managedclusteraddon.go @@ -0,0 +1,55 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + context "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" + scheme "open-cluster-management.io/api/client/addon/clientset/versioned/scheme" +) + +// ManagedClusterAddOnsGetter has a method to return a ManagedClusterAddOnInterface. +// A group's client should implement this interface. +type ManagedClusterAddOnsGetter interface { + ManagedClusterAddOns(namespace string) ManagedClusterAddOnInterface +} + +// ManagedClusterAddOnInterface has methods to work with ManagedClusterAddOn resources. +type ManagedClusterAddOnInterface interface { + Create(ctx context.Context, managedClusterAddOn *addonv1beta1.ManagedClusterAddOn, opts v1.CreateOptions) (*addonv1beta1.ManagedClusterAddOn, error) + Update(ctx context.Context, managedClusterAddOn *addonv1beta1.ManagedClusterAddOn, opts v1.UpdateOptions) (*addonv1beta1.ManagedClusterAddOn, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, managedClusterAddOn *addonv1beta1.ManagedClusterAddOn, opts v1.UpdateOptions) (*addonv1beta1.ManagedClusterAddOn, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*addonv1beta1.ManagedClusterAddOn, error) + List(ctx context.Context, opts v1.ListOptions) (*addonv1beta1.ManagedClusterAddOnList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *addonv1beta1.ManagedClusterAddOn, err error) + ManagedClusterAddOnExpansion +} + +// managedClusterAddOns implements ManagedClusterAddOnInterface +type managedClusterAddOns struct { + *gentype.ClientWithList[*addonv1beta1.ManagedClusterAddOn, *addonv1beta1.ManagedClusterAddOnList] +} + +// newManagedClusterAddOns returns a ManagedClusterAddOns +func newManagedClusterAddOns(c *AddonV1beta1Client, namespace string) *managedClusterAddOns { + return &managedClusterAddOns{ + gentype.NewClientWithList[*addonv1beta1.ManagedClusterAddOn, *addonv1beta1.ManagedClusterAddOnList]( + "managedclusteraddons", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *addonv1beta1.ManagedClusterAddOn { return &addonv1beta1.ManagedClusterAddOn{} }, + func() *addonv1beta1.ManagedClusterAddOnList { return &addonv1beta1.ManagedClusterAddOnList{} }, + ), + } +} diff --git a/client/addon/informers/externalversions/addon/interface.go b/client/addon/informers/externalversions/addon/interface.go index 76c3f628..32c0dd99 100644 --- a/client/addon/informers/externalversions/addon/interface.go +++ b/client/addon/informers/externalversions/addon/interface.go @@ -5,6 +5,7 @@ package addon import ( v1alpha1 "open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1alpha1" + v1beta1 "open-cluster-management.io/api/client/addon/informers/externalversions/addon/v1beta1" internalinterfaces "open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces" ) @@ -12,6 +13,8 @@ import ( type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface } type group struct { @@ -29,3 +32,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/client/addon/informers/externalversions/addon/v1beta1/clustermanagementaddon.go b/client/addon/informers/externalversions/addon/v1beta1/clustermanagementaddon.go new file mode 100644 index 00000000..daaf4cdb --- /dev/null +++ b/client/addon/informers/externalversions/addon/v1beta1/clustermanagementaddon.go @@ -0,0 +1,86 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + context "context" + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + apiaddonv1beta1 "open-cluster-management.io/api/addon/v1beta1" + versioned "open-cluster-management.io/api/client/addon/clientset/versioned" + internalinterfaces "open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces" + addonv1beta1 "open-cluster-management.io/api/client/addon/listers/addon/v1beta1" +) + +// ClusterManagementAddOnInformer provides access to a shared informer and lister for +// ClusterManagementAddOns. +type ClusterManagementAddOnInformer interface { + Informer() cache.SharedIndexInformer + Lister() addonv1beta1.ClusterManagementAddOnLister +} + +type clusterManagementAddOnInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterManagementAddOnInformer constructs a new informer for ClusterManagementAddOn type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterManagementAddOnInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterManagementAddOnInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterManagementAddOnInformer constructs a new informer for ClusterManagementAddOn type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterManagementAddOnInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ClusterManagementAddOns().List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ClusterManagementAddOns().Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ClusterManagementAddOns().List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ClusterManagementAddOns().Watch(ctx, options) + }, + }, + &apiaddonv1beta1.ClusterManagementAddOn{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterManagementAddOnInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterManagementAddOnInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterManagementAddOnInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiaddonv1beta1.ClusterManagementAddOn{}, f.defaultInformer) +} + +func (f *clusterManagementAddOnInformer) Lister() addonv1beta1.ClusterManagementAddOnLister { + return addonv1beta1.NewClusterManagementAddOnLister(f.Informer().GetIndexer()) +} diff --git a/client/addon/informers/externalversions/addon/v1beta1/interface.go b/client/addon/informers/externalversions/addon/v1beta1/interface.go new file mode 100644 index 00000000..0ad83577 --- /dev/null +++ b/client/addon/informers/externalversions/addon/v1beta1/interface.go @@ -0,0 +1,37 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterManagementAddOns returns a ClusterManagementAddOnInformer. + ClusterManagementAddOns() ClusterManagementAddOnInformer + // ManagedClusterAddOns returns a ManagedClusterAddOnInformer. + ManagedClusterAddOns() ManagedClusterAddOnInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterManagementAddOns returns a ClusterManagementAddOnInformer. +func (v *version) ClusterManagementAddOns() ClusterManagementAddOnInformer { + return &clusterManagementAddOnInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// ManagedClusterAddOns returns a ManagedClusterAddOnInformer. +func (v *version) ManagedClusterAddOns() ManagedClusterAddOnInformer { + return &managedClusterAddOnInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/client/addon/informers/externalversions/addon/v1beta1/managedclusteraddon.go b/client/addon/informers/externalversions/addon/v1beta1/managedclusteraddon.go new file mode 100644 index 00000000..f8318f8c --- /dev/null +++ b/client/addon/informers/externalversions/addon/v1beta1/managedclusteraddon.go @@ -0,0 +1,87 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + context "context" + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + apiaddonv1beta1 "open-cluster-management.io/api/addon/v1beta1" + versioned "open-cluster-management.io/api/client/addon/clientset/versioned" + internalinterfaces "open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces" + addonv1beta1 "open-cluster-management.io/api/client/addon/listers/addon/v1beta1" +) + +// ManagedClusterAddOnInformer provides access to a shared informer and lister for +// ManagedClusterAddOns. +type ManagedClusterAddOnInformer interface { + Informer() cache.SharedIndexInformer + Lister() addonv1beta1.ManagedClusterAddOnLister +} + +type managedClusterAddOnInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewManagedClusterAddOnInformer constructs a new informer for ManagedClusterAddOn type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewManagedClusterAddOnInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredManagedClusterAddOnInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredManagedClusterAddOnInformer constructs a new informer for ManagedClusterAddOn type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredManagedClusterAddOnInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ManagedClusterAddOns(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ManagedClusterAddOns(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ManagedClusterAddOns(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.AddonV1beta1().ManagedClusterAddOns(namespace).Watch(ctx, options) + }, + }, + &apiaddonv1beta1.ManagedClusterAddOn{}, + resyncPeriod, + indexers, + ) +} + +func (f *managedClusterAddOnInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredManagedClusterAddOnInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *managedClusterAddOnInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apiaddonv1beta1.ManagedClusterAddOn{}, f.defaultInformer) +} + +func (f *managedClusterAddOnInformer) Lister() addonv1beta1.ManagedClusterAddOnLister { + return addonv1beta1.NewManagedClusterAddOnLister(f.Informer().GetIndexer()) +} diff --git a/client/addon/informers/externalversions/generic.go b/client/addon/informers/externalversions/generic.go index 719107e2..85fbed88 100644 --- a/client/addon/informers/externalversions/generic.go +++ b/client/addon/informers/externalversions/generic.go @@ -9,6 +9,7 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" v1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + v1beta1 "open-cluster-management.io/api/addon/v1beta1" ) // GenericInformer is type of SharedIndexInformer which will locate and delegate to other @@ -47,6 +48,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1alpha1.SchemeGroupVersion.WithResource("managedclusteraddons"): return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1alpha1().ManagedClusterAddOns().Informer()}, nil + // Group=addon.open-cluster-management.io, Version=v1beta1 + case v1beta1.SchemeGroupVersion.WithResource("clustermanagementaddons"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1beta1().ClusterManagementAddOns().Informer()}, nil + case v1beta1.SchemeGroupVersion.WithResource("managedclusteraddons"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1beta1().ManagedClusterAddOns().Informer()}, nil + } return nil, fmt.Errorf("no informer found for %v", resource) diff --git a/client/addon/listers/addon/v1beta1/clustermanagementaddon.go b/client/addon/listers/addon/v1beta1/clustermanagementaddon.go new file mode 100644 index 00000000..e0fcb79f --- /dev/null +++ b/client/addon/listers/addon/v1beta1/clustermanagementaddon.go @@ -0,0 +1,33 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" +) + +// ClusterManagementAddOnLister helps list ClusterManagementAddOns. +// All objects returned here must be treated as read-only. +type ClusterManagementAddOnLister interface { + // List lists all ClusterManagementAddOns in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*addonv1beta1.ClusterManagementAddOn, err error) + // Get retrieves the ClusterManagementAddOn from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*addonv1beta1.ClusterManagementAddOn, error) + ClusterManagementAddOnListerExpansion +} + +// clusterManagementAddOnLister implements the ClusterManagementAddOnLister interface. +type clusterManagementAddOnLister struct { + listers.ResourceIndexer[*addonv1beta1.ClusterManagementAddOn] +} + +// NewClusterManagementAddOnLister returns a new ClusterManagementAddOnLister. +func NewClusterManagementAddOnLister(indexer cache.Indexer) ClusterManagementAddOnLister { + return &clusterManagementAddOnLister{listers.New[*addonv1beta1.ClusterManagementAddOn](indexer, addonv1beta1.Resource("clustermanagementaddon"))} +} diff --git a/client/addon/listers/addon/v1beta1/expansion_generated.go b/client/addon/listers/addon/v1beta1/expansion_generated.go new file mode 100644 index 00000000..83673d16 --- /dev/null +++ b/client/addon/listers/addon/v1beta1/expansion_generated.go @@ -0,0 +1,16 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// ClusterManagementAddOnListerExpansion allows custom methods to be added to +// ClusterManagementAddOnLister. +type ClusterManagementAddOnListerExpansion interface{} + +// ManagedClusterAddOnListerExpansion allows custom methods to be added to +// ManagedClusterAddOnLister. +type ManagedClusterAddOnListerExpansion interface{} + +// ManagedClusterAddOnNamespaceListerExpansion allows custom methods to be added to +// ManagedClusterAddOnNamespaceLister. +type ManagedClusterAddOnNamespaceListerExpansion interface{} diff --git a/client/addon/listers/addon/v1beta1/managedclusteraddon.go b/client/addon/listers/addon/v1beta1/managedclusteraddon.go new file mode 100644 index 00000000..fbfa9638 --- /dev/null +++ b/client/addon/listers/addon/v1beta1/managedclusteraddon.go @@ -0,0 +1,55 @@ +// Copyright Contributors to the Open Cluster Management project +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" +) + +// ManagedClusterAddOnLister helps list ManagedClusterAddOns. +// All objects returned here must be treated as read-only. +type ManagedClusterAddOnLister interface { + // List lists all ManagedClusterAddOns in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*addonv1beta1.ManagedClusterAddOn, err error) + // ManagedClusterAddOns returns an object that can list and get ManagedClusterAddOns. + ManagedClusterAddOns(namespace string) ManagedClusterAddOnNamespaceLister + ManagedClusterAddOnListerExpansion +} + +// managedClusterAddOnLister implements the ManagedClusterAddOnLister interface. +type managedClusterAddOnLister struct { + listers.ResourceIndexer[*addonv1beta1.ManagedClusterAddOn] +} + +// NewManagedClusterAddOnLister returns a new ManagedClusterAddOnLister. +func NewManagedClusterAddOnLister(indexer cache.Indexer) ManagedClusterAddOnLister { + return &managedClusterAddOnLister{listers.New[*addonv1beta1.ManagedClusterAddOn](indexer, addonv1beta1.Resource("managedclusteraddon"))} +} + +// ManagedClusterAddOns returns an object that can list and get ManagedClusterAddOns. +func (s *managedClusterAddOnLister) ManagedClusterAddOns(namespace string) ManagedClusterAddOnNamespaceLister { + return managedClusterAddOnNamespaceLister{listers.NewNamespaced[*addonv1beta1.ManagedClusterAddOn](s.ResourceIndexer, namespace)} +} + +// ManagedClusterAddOnNamespaceLister helps list and get ManagedClusterAddOns. +// All objects returned here must be treated as read-only. +type ManagedClusterAddOnNamespaceLister interface { + // List lists all ManagedClusterAddOns in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*addonv1beta1.ManagedClusterAddOn, err error) + // Get retrieves the ManagedClusterAddOn from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*addonv1beta1.ManagedClusterAddOn, error) + ManagedClusterAddOnNamespaceListerExpansion +} + +// managedClusterAddOnNamespaceLister implements the ManagedClusterAddOnNamespaceLister +// interface. +type managedClusterAddOnNamespaceLister struct { + listers.ResourceIndexer[*addonv1beta1.ManagedClusterAddOn] +} diff --git a/hack/lib/init.sh b/hack/lib/init.sh index 32149fbd..ccfd6ef3 100644 --- a/hack/lib/init.sh +++ b/hack/lib/init.sh @@ -19,6 +19,7 @@ work/v1 \ work/v1alpha1 \ operator/v1 \ addon/v1alpha1 \ +addon/v1beta1 \ " API_PACKAGES="\ @@ -29,7 +30,8 @@ open-cluster-management.io/api/cluster/v1beta2,\ open-cluster-management.io/api/work/v1,\ open-cluster-management.io/api/work/v1alpha1,\ open-cluster-management.io/api/operator/v1,\ -open-cluster-management.io/api/addon/v1alpha1\ +open-cluster-management.io/api/addon/v1alpha1,\ +open-cluster-management.io/api/addon/v1beta1\ " set -x diff --git a/hack/verify-crds.sh b/hack/verify-crds.sh index dbc6f7ab..3140b1f1 100644 --- a/hack/verify-crds.sh +++ b/hack/verify-crds.sh @@ -15,6 +15,7 @@ work/v1/*.crd.yaml work/v1alpha1/*crd.yaml operator/v1/*.crd.yaml addon/v1alpha1/*.crd.yaml +addon/v1beta1/*.crd.yaml " FAILS=false diff --git a/test/integration/api/clustermanagementaddon_test.go b/test/integration/api/clustermanagementaddon_test.go index f4a627c0..3150128b 100644 --- a/test/integration/api/clustermanagementaddon_test.go +++ b/test/integration/api/clustermanagementaddon_test.go @@ -13,6 +13,7 @@ import ( "k8s.io/apimachinery/pkg/util/rand" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" ) var _ = ginkgo.Describe("ClusterManagementAddOn API test", func() { @@ -223,4 +224,205 @@ var _ = ginkgo.Describe("ClusterManagementAddOn API test", func() { gomega.Expect(err).ToNot(gomega.HaveOccurred()) }) + + ginkgo.Describe("ClusterManagementAddOn v1beta1 API test", func() { + ginkgo.It("Should create a ClusterManagementAddOn with v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{ + AddOnMeta: addonv1beta1.AddOnMeta{ + DisplayName: "test-v1beta1", + Description: "for v1beta1 test", + }, + DefaultConfigs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.addon", + Resource: "tests", + }, + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test", + }, + }, + }, + InstallStrategy: addonv1beta1.InstallStrategy{ + Type: addonv1beta1.AddonInstallStrategyManual, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + + ginkgo.It("Should not create a ClusterManagementAddOn with empty spec via client v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{}, + } + + _, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).To(gomega.HaveOccurred()) + }) + + ginkgo.It("Should not create a ClusterManagementAddOn when its configuration resource is empty v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{ + InstallStrategy: addonv1beta1.InstallStrategy{ + Type: addonv1beta1.AddonInstallStrategyManual, + }, + DefaultConfigs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{Group: "test.addon"}, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(errors.IsInvalid(err)).To(gomega.BeTrue()) + }) + + ginkgo.It("Should not create a ClusterManagementAddOn when its configuration name is empty v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{ + InstallStrategy: addonv1beta1.InstallStrategy{ + Type: addonv1beta1.AddonInstallStrategyManual, + }, + DefaultConfigs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.addon", + Resource: "tests", + }, + ConfigReferent: addonv1beta1.ConfigReferent{}, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(errors.IsInvalid(err)).To(gomega.BeTrue()) + }) + + ginkgo.It("Should update the ClusterManagementAddOn status v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{ + InstallStrategy: addonv1beta1.InstallStrategy{ + Type: addonv1beta1.AddonInstallStrategyManual, + }, + }, + } + + cma, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + cma.Status.DefaultConfigReferences = []addonv1beta1.DefaultConfigReference{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + DesiredConfig: &addonv1beta1.ConfigSpecHash{ + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test1", + }, + SpecHash: "test-spec-hash", + }, + }, + } + cma.Status.InstallProgressions = []addonv1beta1.InstallProgression{ + { + PlacementRef: addonv1beta1.PlacementRef{ + Name: "test", + Namespace: testNamespace, + }, + ConfigReferences: []addonv1beta1.InstallConfigReference{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + DesiredConfig: &addonv1beta1.ConfigSpecHash{ + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test2", + }, + SpecHash: "test-spec-hash", + }, + }, + }, + }, + } + + _, err = hubAddonClient.AddonV1beta1().ClusterManagementAddOns().UpdateStatus( + context.TODO(), + cma, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + + ginkgo.It("Should update the ClusterManagementAddOn status with empty status v1beta1", func() { + clusterManagementAddOn := &addonv1beta1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterManagementAddOnName, + }, + Spec: addonv1beta1.ClusterManagementAddOnSpec{ + InstallStrategy: addonv1beta1.InstallStrategy{ + Type: addonv1beta1.AddonInstallStrategyManual, + }, + }, + } + + cma, err := hubAddonClient.AddonV1beta1().ClusterManagementAddOns().Create( + context.TODO(), + clusterManagementAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + _, err = hubAddonClient.AddonV1beta1().ClusterManagementAddOns().UpdateStatus( + context.TODO(), + cma, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + }) }) diff --git a/test/integration/api/managedclusteraddon_test.go b/test/integration/api/managedclusteraddon_test.go index 9f98e521..94a6a3d8 100644 --- a/test/integration/api/managedclusteraddon_test.go +++ b/test/integration/api/managedclusteraddon_test.go @@ -11,6 +11,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/rand" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + addonv1beta1 "open-cluster-management.io/api/addon/v1beta1" ) const installNamespaceMaxLength = 63 @@ -322,4 +323,302 @@ var _ = ginkgo.Describe("ManagedClusterAddOn API test", func() { ) gomega.Expect(errors.IsInvalid(err)).To(gomega.BeTrue()) }) + + ginkgo.Describe("ManagedClusterAddOn v1beta1 API test", func() { + ginkgo.It("Should create a ManagedClusterAddOn with v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{ + Configs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test", + }, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + gomega.Expect(mca).ToNot(gomega.BeNil()) + }) + + ginkgo.It("Should create a ManagedClusterAddOn with empty spec v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{}, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + gomega.Expect(mca).ToNot(gomega.BeNil()) + }) + + ginkgo.It("Should update the ManagedClusterAddOn status without config v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{}, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca.Status.Namespace = testNamespace + mca.Status.Registrations = []addonv1beta1.RegistrationConfig{ + { + Type: addonv1beta1.CSR, + CSR: &addonv1beta1.CSRConfig{ + SignerName: "open-cluster-management.io/addontest", + }, + }, + } + + _, err = hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).UpdateStatus( + context.TODO(), + mca, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + + ginkgo.It("Should update the ManagedClusterAddOn status with KubeClient registration v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{}, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca.Status.Namespace = testNamespace + mca.Status.Registrations = []addonv1beta1.RegistrationConfig{ + { + Type: addonv1beta1.KubeClient, + KubeClient: &addonv1beta1.KubeClientConfig{ + Subject: addonv1beta1.Subject{ + User: "test-user", + Groups: []string{"test-group"}, + }, + }, + }, + } + + _, err = hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).UpdateStatus( + context.TODO(), + mca, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + + ginkgo.It("Update failed with wrong signer name in the ManagedClusterAddOn v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{}, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca.Status.Registrations = []addonv1beta1.RegistrationConfig{ + { + Type: addonv1beta1.CSR, + CSR: &addonv1beta1.CSRConfig{ + SignerName: "addontest", + }, + }, + } + + _, err = hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).UpdateStatus( + context.TODO(), + mca, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).To(gomega.HaveOccurred()) + }) + + ginkgo.It("Should update the ManagedClusterAddOn status with config v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{ + Configs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test", + }, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Get( + context.TODO(), + managedClusterAddOnName, + metav1.GetOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + + mca.Status.ConfigReferences = []addonv1beta1.ConfigReference{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + LastObservedGeneration: 1, + DesiredConfig: &addonv1beta1.ConfigSpecHash{ + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test", + }, + SpecHash: "test-spec-hash", + }, + }, + } + + _, err = hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).UpdateStatus( + context.TODO(), + mca, + metav1.UpdateOptions{}, + ) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + }) + + ginkgo.It("Should not create a ManagedClusterAddOn when its config type is empty v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{ + Configs: []addonv1beta1.AddOnConfig{ + { + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + Name: "test", + }, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(errors.IsInvalid(err)).To(gomega.BeTrue()) + }) + + ginkgo.It("Should not create a ManagedClusterAddOn when its config name is empty v1beta1", func() { + managedClusterAddOn := &addonv1beta1.ManagedClusterAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Name: managedClusterAddOnName, + }, + Spec: addonv1beta1.ManagedClusterAddOnSpec{ + Configs: []addonv1beta1.AddOnConfig{ + { + ConfigGroupResource: addonv1beta1.ConfigGroupResource{ + Group: "test.group", + Resource: "tests", + }, + ConfigReferent: addonv1beta1.ConfigReferent{ + Namespace: testNamespace, + }, + }, + }, + }, + } + + _, err := hubAddonClient.AddonV1beta1().ManagedClusterAddOns(testNamespace).Create( + context.TODO(), + managedClusterAddOn, + metav1.CreateOptions{}, + ) + gomega.Expect(errors.IsInvalid(err)).To(gomega.BeTrue()) + }) + }) }) diff --git a/test/integration/api/suite_test.go b/test/integration/api/suite_test.go index 2e5998de..06af451f 100644 --- a/test/integration/api/suite_test.go +++ b/test/integration/api/suite_test.go @@ -53,6 +53,7 @@ var _ = ginkgo.BeforeSuite(func(done ginkgo.Done) { filepath.Join(".", "cluster", "v1alpha1", "0000_02_clusters.open-cluster-management.io_clusterclaims.crd.yaml"), filepath.Join(".", "cluster", "v1alpha1", "0000_05_clusters.open-cluster-management.io_addonplacementscores.crd.yaml"), filepath.Join(".", "addon", "v1alpha1"), + filepath.Join(".", "addon", "v1beta1"), filepath.Join(".", "operator", "v1", "0000_00_operator.open-cluster-management.io_klusterlets.crd.yaml"), filepath.Join(".", "operator", "v1", "0000_01_operator.open-cluster-management.io_clustermanagers.crd.yaml"), },