🌱 Update api to install addon template CRD (#170)

Signed-off-by: zhujian <jiazhu@redhat.com>
This commit is contained in:
Jian Zhu
2023-06-14 14:26:35 +08:00
committed by GitHub
parent c364d34e47
commit 023cdfd0c3
29 changed files with 1893 additions and 48 deletions

View File

@@ -78,6 +78,7 @@ verify-fmt-imports: install-golang-gci
@output=$$(gci diff --skip-generated -s standard -s default -s "prefix(open-cluster-management.io)" -s "prefix(open-cluster-management.io/ocm)" cmd pkg test dependencymagnet); \
if [ -n "$$output" ]; then \
echo "Diff output is not empty: $$output"; \
echo "Please run 'make fmt-imports' to format the golang files imports automatically." \
exit 1; \
else \
echo "Diff output is empty"; \

View File

@@ -9,7 +9,7 @@ rules:
verbs: ["create", "get", "list", "update", "watch", "patch", "delete", "deletecollection"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch", "update", "patch", "delete"]
verbs: ["list", "watch", "update", "patch", "delete"]
resourceNames:
- "signer-secret"
- "registration-webhook-serving-cert"
@@ -20,9 +20,10 @@ rules:
- "placement-controller-sa-kubeconfig"
- "work-controller-sa-kubeconfig"
- "external-hub-kubeconfig"
# addon manager needs this to sign the customized type csr
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
verbs: ["create", "get"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["create", "get", "list", "update", "watch", "patch", "delete"]
@@ -84,6 +85,9 @@ rules:
- apiGroups: ["addon.open-cluster-management.io"]
resources: [managedclusteraddons/finalizers, "clustermanagementaddons/finalizers"]
verbs: ["update"]
- apiGroups: ["addon.open-cluster-management.io"]
resources: [addondeploymentconfigs, "addontemplates"]
verbs: ["get", "list", "watch"]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
@@ -95,8 +99,7 @@ rules:
verbs: ["update"]
- apiGroups: ["certificates.k8s.io"]
resources: ["signers"]
resourceNames: ["kubernetes.io/kube-apiserver-client"]
verbs: ["approve"]
verbs: ["approve", "sign"]
- apiGroups: ["cluster.open-cluster-management.io"]
resources: ["managedclusters"]
verbs: ["get", "list", "watch", "update", "patch"]

2
go.mod
View File

@@ -26,7 +26,7 @@ require (
k8s.io/klog/v2 v2.90.1
k8s.io/kube-aggregator v0.27.2
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749
open-cluster-management.io/api v0.11.0
open-cluster-management.io/api v0.11.1-0.20230609103311-088e8fe86139
sigs.k8s.io/controller-runtime v0.15.0
sigs.k8s.io/kube-storage-version-migrator v0.0.5
)

4
go.sum
View File

@@ -1096,8 +1096,8 @@ k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY=
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/api v0.11.0 h1:zBxa33Co3wseLBF4HEJobhl0P6ygj+Drhe7Wrfo0/h8=
open-cluster-management.io/api v0.11.0/go.mod h1:WgKUCJ7+Bf40DsOmH1Gdkpyj3joco+QLzrlM6Ak39zE=
open-cluster-management.io/api v0.11.1-0.20230609103311-088e8fe86139 h1:nw/XSv4eDGqmg0ks2PHzrE2uosvjw+D314843G56xGY=
open-cluster-management.io/api v0.11.1-0.20230609103311-088e8fe86139/go.mod h1:WgKUCJ7+Bf40DsOmH1Gdkpyj3joco+QLzrlM6Ak39zE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@@ -51,7 +51,7 @@ spec:
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 defautl configurations for add-on. The default
means there are no default configurations for add-on. The default
is an empty list
items:
properties:
@@ -318,9 +318,10 @@ spec:
subject:
description: '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:addon:{addonName}:{clusterName}:{agentName}",
"groups: ["system:open-cluster-management:addon", "system:open-cluster-management:addon:{addonName}",
"system:authenticated"] }'
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.

View File

@@ -0,0 +1,469 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: addontemplates.addon.open-cluster-management.io
spec:
group: addon.open-cluster-management.io
names:
kind: AddOnTemplate
listKind: AddOnTemplateList
plural: addontemplates
singular: addontemplate
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .spec.addonName
name: ADDON NAME
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: "AddOnTemplate is the Custom Resource object, it is used to describe
how to deploy the addon agent and how to register the addon. \n AddOnTemplate
is a cluster-scoped resource, and will only be used on the hub cluster."
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 the registration configuration for the addon and
the addon agent resources yaml description.
properties:
addonName:
description: AddonName represents the name of the addon which the
template belongs to
type: string
agentSpec:
description: AgentSpec describes what/how the kubernetes resources
of the addon agent to be deployed on a managed cluster.
properties:
deleteOption:
description: DeleteOption represents deletion strategy when the
manifestwork is deleted. Foreground deletion strategy is applied
to all the resource in this manifestwork if it is not set.
properties:
propagationPolicy:
default: Foreground
description: propagationPolicy can be Foreground, Orphan or
SelectivelyOrphan SelectivelyOrphan should be rarely used. It
is provided for cases where particular resources is transfering
ownership from one ManifestWork to another or another management
unit. Setting this value will allow a flow like 1. create
manifestwork/2 to manage foo 2. update manifestwork/1 to
selectively orphan foo 3. remove foo from manifestwork/1
without impacting continuity because manifestwork/2 adopts
it.
enum:
- Foreground
- Orphan
- SelectivelyOrphan
type: string
selectivelyOrphans:
description: selectivelyOrphan represents a list of resources
following orphan deletion stratecy
properties:
orphaningRules:
description: orphaningRules defines a slice of orphaningrule.
Each orphaningrule identifies a single resource included
in this manifestwork
items:
description: OrphaningRule identifies a single resource
included in this manifestwork to be orphaned
properties:
group:
description: Group is the API Group of the Kubernetes
resource, empty string indicates it is in core
group.
type: string
name:
description: Name is the name of the Kubernetes
resource.
type: string
namespace:
description: Name is the namespace of the Kubernetes
resource, empty string indicates it is a cluster
scoped resource.
type: string
resource:
description: Resource is the resource name of the
Kubernetes resource.
type: string
required:
- name
- resource
type: object
type: array
type: object
type: object
executor:
description: Executor is the configuration that makes the work
agent to perform some pre-request processing/checking. e.g.
the executor identity tells the work agent to check the executor
has sufficient permission to write the workloads to the local
managed cluster. Note that nil executor is still supported for
backward-compatibility which indicates that the work agent will
not perform any additional actions before applying resources.
properties:
subject:
description: Subject is the subject identity which the work
agent uses to talk to the local cluster when applying the
resources.
properties:
serviceAccount:
description: ServiceAccount is for identifying which service
account to use by the work agent. Only required if the
type is "ServiceAccount".
properties:
name:
description: Name is the name of the service account.
maxLength: 253
minLength: 1
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$
type: string
namespace:
description: Namespace is the namespace of the service
account.
maxLength: 253
minLength: 1
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$
type: string
required:
- name
- namespace
type: object
type:
description: 'Type is the type of the subject identity.
Supported types are: "ServiceAccount".'
enum:
- ServiceAccount
type: string
required:
- type
type: object
type: object
manifestConfigs:
description: ManifestConfigs represents the configurations of
manifests defined in workload field.
items:
description: ManifestConfigOption represents the configurations
of a manifest defined in workload field.
properties:
feedbackRules:
description: FeedbackRules defines what resource status
field should be returned. If it is not set or empty, no
feedback rules will be honored.
items:
properties:
jsonPaths:
description: JsonPaths defines the json path under
status field to be synced.
items:
properties:
name:
description: Name represents the alias name
for this field
type: string
path:
description: Path represents the json path of
the field under status. The path must point
to a field with single value in the type of
integer, bool or string. If the path points
to a non-existing field, no value will be
returned. If the path points to a structure,
map or slice, no value will be returned and
the status conddition of StatusFeedBackSynced
will be set as false. Ref to https://kubernetes.io/docs/reference/kubectl/jsonpath/
on how to write a jsonPath.
type: string
version:
description: Version is the version of the Kubernetes
resource. If it is not specified, the resource
with the semantically latest version is used
to resolve the path.
type: string
required:
- name
- path
type: object
type: array
type:
description: Type defines the option of how status
can be returned. It can be jsonPaths or wellKnownStatus.
If the type is JSONPaths, user should specify the
jsonPaths field If the type is WellKnownStatus,
certain common fields of status defined by a rule
only for types in in k8s.io/api and open-cluster-management/api
will be reported, If these status fields do not
exist, no values will be reported.
enum:
- WellKnownStatus
- JSONPaths
type: string
required:
- type
type: object
type: array
resourceIdentifier:
description: ResourceIdentifier represents the group, resource,
name and namespace of a resoure. iff this refers to a
resource not created by this manifest work, the related
rules will not be executed.
properties:
group:
description: Group is the API Group of the Kubernetes
resource, empty string indicates it is in core group.
type: string
name:
description: Name is the name of the Kubernetes resource.
type: string
namespace:
description: Name is the namespace of the Kubernetes
resource, empty string indicates it is a cluster scoped
resource.
type: string
resource:
description: Resource is the resource name of the Kubernetes
resource.
type: string
required:
- name
- resource
type: object
updateStrategy:
description: UpdateStrategy defines the strategy to update
this manifest. UpdateStrategy is Update if it is not set.
properties:
serverSideApply:
description: serverSideApply defines the configuration
for server side apply. It is honored only when type
of updateStrategy is ServerSideApply
properties:
fieldManager:
default: work-agent
description: FieldManager is the manager to apply
the resource. It is work-agent by default, but
can be other name with work-agent as the prefix.
pattern: ^work-agent
type: string
force:
description: Force represents to force apply the
manifest.
type: boolean
type: object
type:
default: Update
description: type defines the strategy to update this
manifest, default value is Update. Update type means
to update resource by an update call. CreateOnly type
means do not update resource based on current manifest.
ServerSideApply type means to update resource using
server side apply with work-controller as the field
manager. If there is conflict, the related Applied
condition of manifest will be in the status of False
with the reason of ApplyConflict.
enum:
- Update
- CreateOnly
- ServerSideApply
type: string
required:
- type
type: object
required:
- resourceIdentifier
type: object
type: array
workload:
description: Workload represents the manifest workload to be deployed
on a managed cluster.
properties:
manifests:
description: Manifests represents a list of kuberenetes resources
to be deployed on a managed cluster.
items:
description: Manifest represents a resource to be deployed
on managed cluster.
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
type: array
type: object
type: object
registration:
description: Registration holds the registration configuration for
the addon
items:
description: RegistrationSpec describes how to register an addon
agent to the hub cluster. 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.
During the addon registration process, a csr will be created for
each Registration on the hub cluster. The CSR will be approved
automatically, After the csr is approved on the hub cluster, the
klusterlet agent will create a secret in the installNamespace
for the addon agent. If the RegistrationType type is KubeClient,
the secret name will be "{addon name}-hub-kubeconfig" whose content
includes key/cert and kubeconfig. Otherwise, If the RegistrationType
type is CustomSigner the secret name will be "{addon name}-{signer
name}-client-cert" whose content includes key/cert.
properties:
customSigner:
description: CustomSigner holds the configuration of the CustomSigner
type registration required when the Type is CustomSigner
properties:
signerName:
description: signerName is the name of signer that addon
agent will use to create csr.
maxLength: 571
minLength: 5
type: string
signingCA:
description: SigningCA represents the reference of the secret
on the hub cluster to sign the CSR
properties:
name:
description: Name of the signing CA secret
type: string
namespace:
description: Namespace of the signing CA secret
type: string
required:
- name
- namespace
type: object
subject:
description: '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:
- signingCA
type: object
kubeClient:
description: KubeClient holds the configuration of the KubeClient
type registration
properties:
hubPermissions:
description: HubPermissions represent the permission configurations
of the addon agent to access the hub cluster
items:
description: HubPermissionConfig configures the permission
of the addon agent to access the hub cluster. Will create
a RoleBinding in the same namespace as the managedClusterAddon
to bind the user provided ClusterRole/Role to the "system:open-cluster-management:cluster:<cluster-name>:addon:<addon-name>"
Group.
properties:
roleRef:
description: RoleRef is an reference to the permission
resource. it could be a role or a cluster role,
the user must make sure it exist on the hub cluster.
properties:
apiGroup:
description: APIGroup is the group for the resource
being referenced
type: string
kind:
description: Kind is the type of resource being
referenced
type: string
name:
description: Name is the name of resource being
referenced
type: string
required:
- apiGroup
- kind
- name
type: object
x-kubernetes-map-type: atomic
singleNamespace:
description: SingleNamespace contains the configuration
of SingleNamespace type binding. It is required
when the type is SingleNamespace
properties:
namespace:
type: string
required:
- namespace
type: object
type:
description: 'Type of the permissions setting. It
defines how to bind the roleRef on the hub cluster.
It can be: - CurrentCluster: Bind the roleRef to
the namespace with the same name as the managedCluster.
- SingleNamespace: Bind the roleRef to the namespace
specified by SingleNamespaceBindingConfig.'
enum:
- CurrentCluster
- SingleNamespace
type: string
required:
- roleRef
- type
type: object
type: array
type: object
type:
description: 'Type of the registration configuration, it supports:
- KubeClient: the addon agent can access the hub kube apiserver
with kube style API. the signer name should be "kubernetes.io/kube-apiserver-client".
When this type is used, the KubeClientRegistrationConfig can
be used to define the permission of the addon agent to access
the hub cluster - CustomSigner: the addon agent can access
the hub cluster through user-defined endpoints. When this
type is used, the CustomSignerRegistrationConfig can be used
to define how to issue the client certificate for the addon
agent.'
enum:
- KubeClient
- CustomSigner
type: string
required:
- type
type: object
type: array
required:
- addonName
- agentSpec
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -20,7 +20,7 @@ rules:
- apiGroups: ["cluster.open-cluster-management.io"]
resources: ["managedclusters", "placements", "placementdecisions"]
verbs: ["get", "list", "watch"]
# Allow controller to manage managedclusteraddons/clustermanagementaddons
# Allow controller to manage managedclusteraddons/clustermanagementaddons/addontemplates/addondeploymentconfigs
- apiGroups: ["addon.open-cluster-management.io"]
resources: ["managedclusteraddons/finalizers"]
verbs: ["update"]
@@ -39,7 +39,26 @@ rules:
- apiGroups: ["addon.open-cluster-management.io"]
resources: ["managedclusteraddons/status"]
verbs: ["update", "patch"]
# Allow controller to read manifestworks
- apiGroups: ["addon.open-cluster-management.io"]
resources: ["addontemplates", "addondeploymentconfigs"]
verbs: ["get", "list", "watch"]
# Allow controller to manage manifestworks
- apiGroups: ["work.open-cluster-management.io"]
resources: ["manifestworks"]
verbs: ["get", "list", "watch"]
verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
# addon template controller needs these permissions to approve CSR and sign CA
- apiGroups: ["certificates.k8s.io"]
resources: ["certificatesigningrequests"]
verbs: ["create", "get", "list", "watch"]
- apiGroups: ["certificates.k8s.io"]
resources: ["certificatesigningrequests/approval", "certificatesigningrequests/status"]
verbs: ["update"]
- apiGroups: ["certificates.k8s.io"]
resources: ["signers"]
verbs: ["approve", "sign"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]

View File

@@ -327,7 +327,7 @@ func TestSyncDeploy(t *testing.T) {
}
}
// Check if resources are created as expected
testingcommon.AssertEqualNumber(t, len(createCRDObjects), 11)
testingcommon.AssertEqualNumber(t, len(createCRDObjects), 12)
}
func TestSyncDeployNoWebhook(t *testing.T) {
@@ -367,7 +367,7 @@ func TestSyncDeployNoWebhook(t *testing.T) {
}
}
// Check if resources are created as expected
testingcommon.AssertEqualNumber(t, len(createCRDObjects), 11)
testingcommon.AssertEqualNumber(t, len(createCRDObjects), 12)
}
// TestSyncDelete test cleanup hub deploy
@@ -406,7 +406,7 @@ func TestSyncDelete(t *testing.T) {
}
}
// Check if resources are created as expected
testingcommon.AssertEqualNumber(t, len(deleteCRDActions), 15)
testingcommon.AssertEqualNumber(t, len(deleteCRDActions), 16)
for _, action := range deleteKubeActions {
switch action.Resource.Resource {

View File

@@ -46,6 +46,7 @@ var (
"cluster-manager/hub/0000_01_clusters.open-cluster-management.io_managedclustersetbindings.crd.yaml",
"cluster-manager/hub/0000_02_clusters.open-cluster-management.io_placements.crd.yaml",
"cluster-manager/hub/0000_02_addon.open-cluster-management.io_addondeploymentconfigs.crd.yaml",
"cluster-manager/hub/0000_03_addon.open-cluster-management.io_addontemplates.crd.yaml",
"cluster-manager/hub/0000_03_clusters.open-cluster-management.io_placementdecisions.crd.yaml",
"cluster-manager/hub/0000_05_clusters.open-cluster-management.io_addonplacementscores.crd.yaml",
}

View File

@@ -16,7 +16,6 @@ import (
"k8s.io/client-go/util/cert"
operatorapiv1 "open-cluster-management.io/api/operator/v1"
v1 "open-cluster-management.io/api/operator/v1"
"open-cluster-management.io/ocm/pkg/operator/helpers"
"open-cluster-management.io/ocm/test/integration/util"
@@ -83,7 +82,7 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() {
_, _, err = resourceapply.ApplySecret(hostedCtx, hostedKubeClient.CoreV1(), recorder, hubKubeconfigSecret)
gomega.Expect(err).To(gomega.BeNil())
go startHubOperator(hostedCtx, v1.InstallModeHosted)
go startHubOperator(hostedCtx, operatorapiv1.InstallModeHosted)
})
ginkgo.AfterEach(func() {
@@ -338,8 +337,8 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 43 {
return fmt.Errorf("should get 43 relatedResources, actual got %v, %v", len(actual.Status.RelatedResources), actual.Status.RelatedResources)
if len(actual.Status.RelatedResources) != 44 {
return fmt.Errorf("should get 44s relatedResources, actual got %v, %v", len(actual.Status.RelatedResources), actual.Status.RelatedResources)
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -396,8 +395,8 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 39 {
return fmt.Errorf("should get 39 relatedResources, actual got %v", len(actual.Status.RelatedResources))
if len(actual.Status.RelatedResources) != 40 {
return fmt.Errorf("should get 40 relatedResources, actual got %v", len(actual.Status.RelatedResources))
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -474,8 +473,8 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 39 {
return fmt.Errorf("should get 39 relatedResources, actual got %v", len(actual.Status.RelatedResources))
if len(actual.Status.RelatedResources) != 40 {
return fmt.Errorf("should get 40 relatedResources, actual got %v", len(actual.Status.RelatedResources))
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -487,7 +486,7 @@ var _ = ginkgo.Describe("ClusterManager Hosted Mode", func() {
if err != nil {
return err
}
clusterManager.Spec.NodePlacement = v1.NodePlacement{
clusterManager.Spec.NodePlacement = operatorapiv1.NodePlacement{
NodeSelector: map[string]string{"node-role.kubernetes.io/infra": ""},
Tolerations: []corev1.Toleration{
{

View File

@@ -16,7 +16,6 @@ import (
"k8s.io/client-go/util/cert"
operatorapiv1 "open-cluster-management.io/api/operator/v1"
v1 "open-cluster-management.io/api/operator/v1"
"open-cluster-management.io/ocm/pkg/operator/helpers"
"open-cluster-management.io/ocm/pkg/operator/operators/clustermanager"
@@ -24,16 +23,16 @@ import (
"open-cluster-management.io/ocm/test/integration/util"
)
func startHubOperator(ctx context.Context, mode v1.InstallMode) {
func startHubOperator(ctx context.Context, mode operatorapiv1.InstallMode) {
certrotation.SigningCertValidity = time.Second * 30
certrotation.TargetCertValidity = time.Second * 10
certrotation.ResyncInterval = time.Second * 1
var config *rest.Config
switch mode {
case v1.InstallModeDefault:
case operatorapiv1.InstallModeDefault:
config = restConfig
case v1.InstallModeHosted:
case operatorapiv1.InstallModeHosted:
config = hostedRestConfig
}
@@ -67,7 +66,7 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() {
ginkgo.BeforeEach(func() {
var ctx context.Context
ctx, cancel = context.WithCancel(context.Background())
go startHubOperator(ctx, v1.InstallModeDefault)
go startHubOperator(ctx, operatorapiv1.InstallModeDefault)
})
ginkgo.AfterEach(func() {
@@ -333,8 +332,8 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 43 {
return fmt.Errorf("should get 43 relatedResources, actual got %v", len(actual.Status.RelatedResources))
if len(actual.Status.RelatedResources) != 44 {
return fmt.Errorf("should get 44 relatedResources, actual got %v", len(actual.Status.RelatedResources))
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -391,8 +390,8 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 39 {
return fmt.Errorf("should get 39 relatedResources, actual got %v", len(actual.Status.RelatedResources))
if len(actual.Status.RelatedResources) != 40 {
return fmt.Errorf("should get 40 relatedResources, actual got %v", len(actual.Status.RelatedResources))
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -465,8 +464,8 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() {
if err != nil {
return err
}
if len(actual.Status.RelatedResources) != 39 {
return fmt.Errorf("should get 39 relatedResources, actual got %v", len(actual.Status.RelatedResources))
if len(actual.Status.RelatedResources) != 40 {
return fmt.Errorf("should get 40 relatedResources, actual got %v", len(actual.Status.RelatedResources))
}
return nil
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
@@ -478,7 +477,7 @@ var _ = ginkgo.Describe("ClusterManager Default Mode", func() {
if err != nil {
return err
}
clusterManager.Spec.NodePlacement = v1.NodePlacement{
clusterManager.Spec.NodePlacement = operatorapiv1.NodePlacement{
NodeSelector: map[string]string{"node-role.kubernetes.io/infra": ""},
Tolerations: []corev1.Toleration{
{

2
vendor/modules.txt vendored
View File

@@ -1334,7 +1334,7 @@ k8s.io/utils/path
k8s.io/utils/pointer
k8s.io/utils/strings/slices
k8s.io/utils/trace
# open-cluster-management.io/api v0.11.0
# open-cluster-management.io/api v0.11.1-0.20230609103311-088e8fe86139
## explicit; go 1.19
open-cluster-management.io/api/addon/v1alpha1
open-cluster-management.io/api/client/addon/clientset/versioned

View File

@@ -51,7 +51,7 @@ spec:
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 defautl configurations for add-on. The default
means there are no default configurations for add-on. The default
is an empty list
items:
properties:
@@ -318,9 +318,10 @@ spec:
subject:
description: '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:addon:{addonName}:{clusterName}:{agentName}",
"groups: ["system:open-cluster-management:addon", "system:open-cluster-management:addon:{addonName}",
"system:authenticated"] }'
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.

View File

@@ -0,0 +1,469 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
creationTimestamp: null
name: addontemplates.addon.open-cluster-management.io
spec:
group: addon.open-cluster-management.io
names:
kind: AddOnTemplate
listKind: AddOnTemplateList
plural: addontemplates
singular: addontemplate
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .spec.addonName
name: ADDON NAME
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: "AddOnTemplate is the Custom Resource object, it is used to describe
how to deploy the addon agent and how to register the addon. \n AddOnTemplate
is a cluster-scoped resource, and will only be used on the hub cluster."
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 the registration configuration for the addon and
the addon agent resources yaml description.
properties:
addonName:
description: AddonName represents the name of the addon which the
template belongs to
type: string
agentSpec:
description: AgentSpec describes what/how the kubernetes resources
of the addon agent to be deployed on a managed cluster.
properties:
deleteOption:
description: DeleteOption represents deletion strategy when the
manifestwork is deleted. Foreground deletion strategy is applied
to all the resource in this manifestwork if it is not set.
properties:
propagationPolicy:
default: Foreground
description: propagationPolicy can be Foreground, Orphan or
SelectivelyOrphan SelectivelyOrphan should be rarely used. It
is provided for cases where particular resources is transfering
ownership from one ManifestWork to another or another management
unit. Setting this value will allow a flow like 1. create
manifestwork/2 to manage foo 2. update manifestwork/1 to
selectively orphan foo 3. remove foo from manifestwork/1
without impacting continuity because manifestwork/2 adopts
it.
enum:
- Foreground
- Orphan
- SelectivelyOrphan
type: string
selectivelyOrphans:
description: selectivelyOrphan represents a list of resources
following orphan deletion stratecy
properties:
orphaningRules:
description: orphaningRules defines a slice of orphaningrule.
Each orphaningrule identifies a single resource included
in this manifestwork
items:
description: OrphaningRule identifies a single resource
included in this manifestwork to be orphaned
properties:
group:
description: Group is the API Group of the Kubernetes
resource, empty string indicates it is in core
group.
type: string
name:
description: Name is the name of the Kubernetes
resource.
type: string
namespace:
description: Name is the namespace of the Kubernetes
resource, empty string indicates it is a cluster
scoped resource.
type: string
resource:
description: Resource is the resource name of the
Kubernetes resource.
type: string
required:
- name
- resource
type: object
type: array
type: object
type: object
executor:
description: Executor is the configuration that makes the work
agent to perform some pre-request processing/checking. e.g.
the executor identity tells the work agent to check the executor
has sufficient permission to write the workloads to the local
managed cluster. Note that nil executor is still supported for
backward-compatibility which indicates that the work agent will
not perform any additional actions before applying resources.
properties:
subject:
description: Subject is the subject identity which the work
agent uses to talk to the local cluster when applying the
resources.
properties:
serviceAccount:
description: ServiceAccount is for identifying which service
account to use by the work agent. Only required if the
type is "ServiceAccount".
properties:
name:
description: Name is the name of the service account.
maxLength: 253
minLength: 1
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$
type: string
namespace:
description: Namespace is the namespace of the service
account.
maxLength: 253
minLength: 1
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)$
type: string
required:
- name
- namespace
type: object
type:
description: 'Type is the type of the subject identity.
Supported types are: "ServiceAccount".'
enum:
- ServiceAccount
type: string
required:
- type
type: object
type: object
manifestConfigs:
description: ManifestConfigs represents the configurations of
manifests defined in workload field.
items:
description: ManifestConfigOption represents the configurations
of a manifest defined in workload field.
properties:
feedbackRules:
description: FeedbackRules defines what resource status
field should be returned. If it is not set or empty, no
feedback rules will be honored.
items:
properties:
jsonPaths:
description: JsonPaths defines the json path under
status field to be synced.
items:
properties:
name:
description: Name represents the alias name
for this field
type: string
path:
description: Path represents the json path of
the field under status. The path must point
to a field with single value in the type of
integer, bool or string. If the path points
to a non-existing field, no value will be
returned. If the path points to a structure,
map or slice, no value will be returned and
the status conddition of StatusFeedBackSynced
will be set as false. Ref to https://kubernetes.io/docs/reference/kubectl/jsonpath/
on how to write a jsonPath.
type: string
version:
description: Version is the version of the Kubernetes
resource. If it is not specified, the resource
with the semantically latest version is used
to resolve the path.
type: string
required:
- name
- path
type: object
type: array
type:
description: Type defines the option of how status
can be returned. It can be jsonPaths or wellKnownStatus.
If the type is JSONPaths, user should specify the
jsonPaths field If the type is WellKnownStatus,
certain common fields of status defined by a rule
only for types in in k8s.io/api and open-cluster-management/api
will be reported, If these status fields do not
exist, no values will be reported.
enum:
- WellKnownStatus
- JSONPaths
type: string
required:
- type
type: object
type: array
resourceIdentifier:
description: ResourceIdentifier represents the group, resource,
name and namespace of a resoure. iff this refers to a
resource not created by this manifest work, the related
rules will not be executed.
properties:
group:
description: Group is the API Group of the Kubernetes
resource, empty string indicates it is in core group.
type: string
name:
description: Name is the name of the Kubernetes resource.
type: string
namespace:
description: Name is the namespace of the Kubernetes
resource, empty string indicates it is a cluster scoped
resource.
type: string
resource:
description: Resource is the resource name of the Kubernetes
resource.
type: string
required:
- name
- resource
type: object
updateStrategy:
description: UpdateStrategy defines the strategy to update
this manifest. UpdateStrategy is Update if it is not set.
properties:
serverSideApply:
description: serverSideApply defines the configuration
for server side apply. It is honored only when type
of updateStrategy is ServerSideApply
properties:
fieldManager:
default: work-agent
description: FieldManager is the manager to apply
the resource. It is work-agent by default, but
can be other name with work-agent as the prefix.
pattern: ^work-agent
type: string
force:
description: Force represents to force apply the
manifest.
type: boolean
type: object
type:
default: Update
description: type defines the strategy to update this
manifest, default value is Update. Update type means
to update resource by an update call. CreateOnly type
means do not update resource based on current manifest.
ServerSideApply type means to update resource using
server side apply with work-controller as the field
manager. If there is conflict, the related Applied
condition of manifest will be in the status of False
with the reason of ApplyConflict.
enum:
- Update
- CreateOnly
- ServerSideApply
type: string
required:
- type
type: object
required:
- resourceIdentifier
type: object
type: array
workload:
description: Workload represents the manifest workload to be deployed
on a managed cluster.
properties:
manifests:
description: Manifests represents a list of kuberenetes resources
to be deployed on a managed cluster.
items:
description: Manifest represents a resource to be deployed
on managed cluster.
type: object
x-kubernetes-embedded-resource: true
x-kubernetes-preserve-unknown-fields: true
type: array
type: object
type: object
registration:
description: Registration holds the registration configuration for
the addon
items:
description: RegistrationSpec describes how to register an addon
agent to the hub cluster. 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.
During the addon registration process, a csr will be created for
each Registration on the hub cluster. The CSR will be approved
automatically, After the csr is approved on the hub cluster, the
klusterlet agent will create a secret in the installNamespace
for the addon agent. If the RegistrationType type is KubeClient,
the secret name will be "{addon name}-hub-kubeconfig" whose content
includes key/cert and kubeconfig. Otherwise, If the RegistrationType
type is CustomSigner the secret name will be "{addon name}-{signer
name}-client-cert" whose content includes key/cert.
properties:
customSigner:
description: CustomSigner holds the configuration of the CustomSigner
type registration required when the Type is CustomSigner
properties:
signerName:
description: signerName is the name of signer that addon
agent will use to create csr.
maxLength: 571
minLength: 5
type: string
signingCA:
description: SigningCA represents the reference of the secret
on the hub cluster to sign the CSR
properties:
name:
description: Name of the signing CA secret
type: string
namespace:
description: Namespace of the signing CA secret
type: string
required:
- name
- namespace
type: object
subject:
description: '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:
- signingCA
type: object
kubeClient:
description: KubeClient holds the configuration of the KubeClient
type registration
properties:
hubPermissions:
description: HubPermissions represent the permission configurations
of the addon agent to access the hub cluster
items:
description: HubPermissionConfig configures the permission
of the addon agent to access the hub cluster. Will create
a RoleBinding in the same namespace as the managedClusterAddon
to bind the user provided ClusterRole/Role to the "system:open-cluster-management:cluster:<cluster-name>:addon:<addon-name>"
Group.
properties:
roleRef:
description: RoleRef is an reference to the permission
resource. it could be a role or a cluster role,
the user must make sure it exist on the hub cluster.
properties:
apiGroup:
description: APIGroup is the group for the resource
being referenced
type: string
kind:
description: Kind is the type of resource being
referenced
type: string
name:
description: Name is the name of resource being
referenced
type: string
required:
- apiGroup
- kind
- name
type: object
x-kubernetes-map-type: atomic
singleNamespace:
description: SingleNamespace contains the configuration
of SingleNamespace type binding. It is required
when the type is SingleNamespace
properties:
namespace:
type: string
required:
- namespace
type: object
type:
description: 'Type of the permissions setting. It
defines how to bind the roleRef on the hub cluster.
It can be: - CurrentCluster: Bind the roleRef to
the namespace with the same name as the managedCluster.
- SingleNamespace: Bind the roleRef to the namespace
specified by SingleNamespaceBindingConfig.'
enum:
- CurrentCluster
- SingleNamespace
type: string
required:
- roleRef
- type
type: object
type: array
type: object
type:
description: 'Type of the registration configuration, it supports:
- KubeClient: the addon agent can access the hub kube apiserver
with kube style API. the signer name should be "kubernetes.io/kube-apiserver-client".
When this type is used, the KubeClientRegistrationConfig can
be used to define the permission of the addon agent to access
the hub cluster - CustomSigner: the addon agent can access
the hub cluster through user-defined endpoints. When this
type is used, the CustomSignerRegistrationConfig can be used
to define how to issue the client certificate for the addon
agent.'
enum:
- KubeClient
- CustomSigner
type: string
required:
- type
type: object
type: array
required:
- addonName
- agentSpec
type: object
required:
- spec
type: object
served: true
storage: true
subresources: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -36,6 +36,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&ManagedClusterAddOnList{},
&AddOnDeploymentConfig{},
&AddOnDeploymentConfigList{},
&AddOnTemplate{},
&AddOnTemplateList{},
)
metav1.AddToGroupVersion(scheme, GroupVersion)
return nil

View File

@@ -0,0 +1,184 @@
package v1alpha1
import (
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
work "open-cluster-management.io/api/work/v1"
)
// +genclient
// +genclient:nonNamespaced
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:resource:scope="Cluster"
// +kubebuilder:printcolumn:name="ADDON NAME",type=string,JSONPath=`.spec.addonName`
// AddOnTemplate is the Custom Resource object, it is used to describe
// how to deploy the addon agent and how to register the addon.
//
// AddOnTemplate is a cluster-scoped resource, and will only be used
// on the hub cluster.
type AddOnTemplate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
// spec holds the registration configuration for the addon and the
// addon agent resources yaml description.
// +kubebuilder:validation:Required
// +required
Spec AddOnTemplateSpec `json:"spec"`
}
// AddOnTemplateSpec defines the template of an addon agent which will be deployed on managed clusters.
type AddOnTemplateSpec struct {
// AddonName represents the name of the addon which the template belongs to
// +kubebuilder:validation:Required
// +required
AddonName string `json:"addonName"`
// AgentSpec describes what/how the kubernetes resources of the addon agent to be deployed on a managed cluster.
// +kubebuilder:validation:Required
// +required
AgentSpec work.ManifestWorkSpec `json:"agentSpec"`
// Registration holds the registration configuration for the addon
// +optional
Registration []RegistrationSpec `json:"registration"`
}
// RegistrationType represents the type of the registration configuration,
// it could be KubeClient or CustomSigner
type RegistrationType string
// HubPermissionsBindingType represent how to bind permission resources(role/clusterrole)
// on the hub cluster for the addon agent
type HubPermissionsBindingType string
const (
// RegistrationTypeKubeClient represents the KubeClient type registration of the addon agent.
// For this type, the addon agent can access the hub kube apiserver with kube style API.
// The signer name should be "kubernetes.io/kube-apiserver-client".
RegistrationTypeKubeClient RegistrationType = "KubeClient"
// RegistrationTypeCustomSigner represents the CustomSigner type registration of the addon agent.
// For this type, the addon agent can access the hub cluster through user-defined endpoints.
RegistrationTypeCustomSigner RegistrationType = "CustomSigner"
// HubPermissionsBindingSingleNamespace means that will only allow the addon agent to access the
// resources in a single user defined namespace on the hub cluster.
HubPermissionsBindingSingleNamespace HubPermissionsBindingType = "SingleNamespace"
// HubPermissionsBindingCurrentCluster means that will only allow the addon agent to access the
// resources in managed cluster namespace on the hub cluster.
// It is a specific case of the SingleNamespace type.
HubPermissionsBindingCurrentCluster HubPermissionsBindingType = "CurrentCluster"
)
// RegistrationSpec describes how to register an addon agent to the hub cluster.
// 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. During the addon
// registration process, a csr will be created for each Registration on the hub cluster. The
// CSR will be approved automatically, After the csr is approved on the hub cluster, the klusterlet
// agent will create a secret in the installNamespace for the addon agent.
// If the RegistrationType type is KubeClient, the secret name will be "{addon name}-hub-kubeconfig"
// whose content includes key/cert and kubeconfig. Otherwise, If the RegistrationType type is
// CustomSigner the secret name will be "{addon name}-{signer name}-client-cert" whose content
// includes key/cert.
type RegistrationSpec struct {
// Type of the registration configuration, it supports:
// - KubeClient: the addon agent can access the hub kube apiserver with kube style API.
// the signer name should be "kubernetes.io/kube-apiserver-client". When this type is
// used, the KubeClientRegistrationConfig can be used to define the permission of the
// addon agent to access the hub cluster
// - CustomSigner: the addon agent can access the hub cluster through user-defined endpoints.
// When this type is used, the CustomSignerRegistrationConfig can be used to define how
// to issue the client certificate for the addon agent.
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum:=KubeClient;CustomSigner
Type RegistrationType `json:"type"`
// KubeClient holds the configuration of the KubeClient type registration
// +optional
KubeClient *KubeClientRegistrationConfig `json:"kubeClient,omitempty"`
// CustomSigner holds the configuration of the CustomSigner type registration
// required when the Type is CustomSigner
CustomSigner *CustomSignerRegistrationConfig `json:"customSigner,omitempty"`
}
type KubeClientRegistrationConfig struct {
// HubPermissions represent the permission configurations of the addon agent to access the hub cluster
// +optional
HubPermissions []HubPermissionConfig `json:"hubPermissions,omitempty"`
}
// HubPermissionConfig configures the permission of the addon agent to access the hub cluster.
// Will create a RoleBinding in the same namespace as the managedClusterAddon to bind the user
// provided ClusterRole/Role to the "system:open-cluster-management:cluster:<cluster-name>:addon:<addon-name>"
// Group.
type HubPermissionConfig struct {
// Type of the permissions setting. It defines how to bind the roleRef on the hub cluster. It can be:
// - CurrentCluster: Bind the roleRef to the namespace with the same name as the managedCluster.
// - SingleNamespace: Bind the roleRef to the namespace specified by SingleNamespaceBindingConfig.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:Enum:=CurrentCluster;SingleNamespace
Type HubPermissionsBindingType `json:"type"`
// RoleRef is an reference to the permission resource. it could be a role or a cluster role,
// the user must make sure it exist on the hub cluster.
// +kubebuilder:validation:Required
RoleRef rbacv1.RoleRef `json:"roleRef"`
// SingleNamespace contains the configuration of SingleNamespace type binding.
// It is required when the type is SingleNamespace
SingleNamespace *SingleNamespaceBindingConfig `json:"singleNamespace,omitempty"`
}
type SingleNamespaceBindingConfig struct {
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`
}
type CustomSignerRegistrationConfig struct {
// signerName is the name of signer that addon agent will use to create csr.
// +required
// +kubebuilder:validation:MaxLength=571
// +kubebuilder:validation:MinLength=5
SignerName string `json:"signerName"`
// 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"]
// }
Subject *Subject `json:"subject,omitempty"`
// SigningCA represents the reference of the secret on the hub cluster to sign the CSR
// +kubebuilder:validation:Required
SigningCA SigningCARef `json:"signingCA"`
}
// SigningCARef is the reference to the signing CA secret that must contain the
// certificate authority data with key "ca.crt" and the private key data with key "ca.key"
type SigningCARef struct {
// Namespace of the signing CA secret
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`
// Name of the signing CA secret
// +kubebuilder:validation:Required
Name string `json:"name"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// AddOnTemplateList is a collection of addon templates.
type AddOnTemplateList 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 addon templates.
Items []AddOnTemplate `json:"items"`
}

View File

@@ -43,7 +43,7 @@ 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 defautl configurations for add-on.
// An empty list means there are no default configurations for add-on.
// The default is an empty list
// +optional
Configs []AddOnConfig `json:"configs,omitempty"`
@@ -61,8 +61,9 @@ type RegistrationConfig struct {
// 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:addon:{addonName}:{clusterName}:{agentName}",
// "groups: ["system:open-cluster-management:addon", "system:open-cluster-management:addon:{addonName}", "system:authenticated"]
// "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"]
// }
//
// +optional

View File

@@ -136,6 +136,90 @@ func (in *AddOnMeta) DeepCopy() *AddOnMeta {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AddOnTemplate) DeepCopyInto(out *AddOnTemplate) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddOnTemplate.
func (in *AddOnTemplate) DeepCopy() *AddOnTemplate {
if in == nil {
return nil
}
out := new(AddOnTemplate)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *AddOnTemplate) 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 *AddOnTemplateList) DeepCopyInto(out *AddOnTemplateList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]AddOnTemplate, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddOnTemplateList.
func (in *AddOnTemplateList) DeepCopy() *AddOnTemplateList {
if in == nil {
return nil
}
out := new(AddOnTemplateList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *AddOnTemplateList) 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 *AddOnTemplateSpec) DeepCopyInto(out *AddOnTemplateSpec) {
*out = *in
in.AgentSpec.DeepCopyInto(&out.AgentSpec)
if in.Registration != nil {
in, out := &in.Registration, &out.Registration
*out = make([]RegistrationSpec, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddOnTemplateSpec.
func (in *AddOnTemplateSpec) DeepCopy() *AddOnTemplateSpec {
if in == nil {
return nil
}
out := new(AddOnTemplateSpec)
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
@@ -368,6 +452,28 @@ func (in *ConfigSpecHash) DeepCopy() *ConfigSpecHash {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomSignerRegistrationConfig) DeepCopyInto(out *CustomSignerRegistrationConfig) {
*out = *in
if in.Subject != nil {
in, out := &in.Subject, &out.Subject
*out = new(Subject)
(*in).DeepCopyInto(*out)
}
out.SigningCA = in.SigningCA
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomSignerRegistrationConfig.
func (in *CustomSignerRegistrationConfig) DeepCopy() *CustomSignerRegistrationConfig {
if in == nil {
return nil
}
out := new(CustomSignerRegistrationConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomizedVariable) DeepCopyInto(out *CustomizedVariable) {
*out = *in
@@ -422,6 +528,28 @@ func (in *HealthCheck) DeepCopy() *HealthCheck {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HubPermissionConfig) DeepCopyInto(out *HubPermissionConfig) {
*out = *in
out.RoleRef = in.RoleRef
if in.SingleNamespace != nil {
in, out := &in.SingleNamespace, &out.SingleNamespace
*out = new(SingleNamespaceBindingConfig)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubPermissionConfig.
func (in *HubPermissionConfig) DeepCopy() *HubPermissionConfig {
if in == nil {
return nil
}
out := new(HubPermissionConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ImageMirror) DeepCopyInto(out *ImageMirror) {
*out = *in
@@ -524,6 +652,29 @@ func (in *InstallStrategy) DeepCopy() *InstallStrategy {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeClientRegistrationConfig) DeepCopyInto(out *KubeClientRegistrationConfig) {
*out = *in
if in.HubPermissions != nil {
in, out := &in.HubPermissions, &out.HubPermissions
*out = make([]HubPermissionConfig, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeClientRegistrationConfig.
func (in *KubeClientRegistrationConfig) DeepCopy() *KubeClientRegistrationConfig {
if in == nil {
return nil
}
out := new(KubeClientRegistrationConfig)
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
@@ -758,6 +909,32 @@ func (in *RegistrationConfig) DeepCopy() *RegistrationConfig {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RegistrationSpec) DeepCopyInto(out *RegistrationSpec) {
*out = *in
if in.KubeClient != nil {
in, out := &in.KubeClient, &out.KubeClient
*out = new(KubeClientRegistrationConfig)
(*in).DeepCopyInto(*out)
}
if in.CustomSigner != nil {
in, out := &in.CustomSigner, &out.CustomSigner
*out = new(CustomSignerRegistrationConfig)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistrationSpec.
func (in *RegistrationSpec) DeepCopy() *RegistrationSpec {
if in == nil {
return nil
}
out := new(RegistrationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RollingUpdate) DeepCopyInto(out *RollingUpdate) {
*out = *in
@@ -819,6 +996,38 @@ func (in *RolloutStrategy) DeepCopy() *RolloutStrategy {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SigningCARef) DeepCopyInto(out *SigningCARef) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SigningCARef.
func (in *SigningCARef) DeepCopy() *SigningCARef {
if in == nil {
return nil
}
out := new(SigningCARef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SingleNamespaceBindingConfig) DeepCopyInto(out *SingleNamespaceBindingConfig) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SingleNamespaceBindingConfig.
func (in *SingleNamespaceBindingConfig) DeepCopy() *SingleNamespaceBindingConfig {
if in == nil {
return nil
}
out := new(SingleNamespaceBindingConfig)
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

View File

@@ -70,6 +70,86 @@ func (NodePlacement) SwaggerDoc() map[string]string {
return map_NodePlacement
}
var map_AddOnTemplate = map[string]string{
"": "AddOnTemplate is the Custom Resource object, it is used to describe how to deploy the addon agent and how to register the addon.\n\nAddOnTemplate is a cluster-scoped resource, and will only be used on the hub cluster.",
"spec": "spec holds the registration configuration for the addon and the addon agent resources yaml description.",
}
func (AddOnTemplate) SwaggerDoc() map[string]string {
return map_AddOnTemplate
}
var map_AddOnTemplateList = map[string]string{
"": "AddOnTemplateList is a collection of addon templates.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"items": "Items is a list of addon templates.",
}
func (AddOnTemplateList) SwaggerDoc() map[string]string {
return map_AddOnTemplateList
}
var map_AddOnTemplateSpec = map[string]string{
"": "AddOnTemplateSpec defines the template of an addon agent which will be deployed on managed clusters.",
"addonName": "AddonName represents the name of the addon which the template belongs to",
"agentSpec": "AgentSpec describes what/how the kubernetes resources of the addon agent to be deployed on a managed cluster.",
"registration": "Registration holds the registration configuration for the addon",
}
func (AddOnTemplateSpec) SwaggerDoc() map[string]string {
return map_AddOnTemplateSpec
}
var map_CustomSignerRegistrationConfig = map[string]string{
"signerName": "signerName is the name of signer that addon agent will use to create csr.",
"subject": "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\": {\n \"user\": \"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}:agent:{agentName}\",\n \"groups: [\"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}\",\n \"system:open-cluster-management:addon:{addonName}\", \"system:authenticated\"]\n}",
"signingCA": "SigningCA represents the reference of the secret on the hub cluster to sign the CSR",
}
func (CustomSignerRegistrationConfig) SwaggerDoc() map[string]string {
return map_CustomSignerRegistrationConfig
}
var map_HubPermissionConfig = map[string]string{
"": "HubPermissionConfig configures the permission of the addon agent to access the hub cluster. Will create a RoleBinding in the same namespace as the managedClusterAddon to bind the user provided ClusterRole/Role to the \"system:open-cluster-management:cluster:<cluster-name>:addon:<addon-name>\" Group.",
"type": "Type of the permissions setting. It defines how to bind the roleRef on the hub cluster. It can be: - CurrentCluster: Bind the roleRef to the namespace with the same name as the managedCluster. - SingleNamespace: Bind the roleRef to the namespace specified by SingleNamespaceBindingConfig.",
"roleRef": "RoleRef is an reference to the permission resource. it could be a role or a cluster role, the user must make sure it exist on the hub cluster.",
"singleNamespace": "SingleNamespace contains the configuration of SingleNamespace type binding. It is required when the type is SingleNamespace",
}
func (HubPermissionConfig) SwaggerDoc() map[string]string {
return map_HubPermissionConfig
}
var map_KubeClientRegistrationConfig = map[string]string{
"hubPermissions": "HubPermissions represent the permission configurations of the addon agent to access the hub cluster",
}
func (KubeClientRegistrationConfig) SwaggerDoc() map[string]string {
return map_KubeClientRegistrationConfig
}
var map_RegistrationSpec = map[string]string{
"": "RegistrationSpec describes how to register an addon agent to the hub cluster. 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. During the addon registration process, a csr will be created for each Registration on the hub cluster. The CSR will be approved automatically, After the csr is approved on the hub cluster, the klusterlet agent will create a secret in the installNamespace for the addon agent. If the RegistrationType type is KubeClient, the secret name will be \"{addon name}-hub-kubeconfig\" whose content includes key/cert and kubeconfig. Otherwise, If the RegistrationType type is CustomSigner the secret name will be \"{addon name}-{signer name}-client-cert\" whose content includes key/cert.",
"type": "Type of the registration configuration, it supports: - KubeClient: the addon agent can access the hub kube apiserver with kube style API.\n the signer name should be \"kubernetes.io/kube-apiserver-client\". When this type is\n used, the KubeClientRegistrationConfig can be used to define the permission of the\n addon agent to access the hub cluster\n- CustomSigner: the addon agent can access the hub cluster through user-defined endpoints.\n When this type is used, the CustomSignerRegistrationConfig can be used to define how\n to issue the client certificate for the addon agent.",
"kubeClient": "KubeClient holds the configuration of the KubeClient type registration",
"customSigner": "CustomSigner holds the configuration of the CustomSigner type registration required when the Type is CustomSigner",
}
func (RegistrationSpec) SwaggerDoc() map[string]string {
return map_RegistrationSpec
}
var map_SigningCARef = map[string]string{
"": "SigningCARef is the reference to the signing CA secret that must contain the certificate authority data with key \"ca.crt\" and the private key data with key \"ca.key\"",
"namespace": "Namespace of the signing CA secret",
"name": "Name of the signing CA secret",
}
func (SigningCARef) SwaggerDoc() map[string]string {
return map_SigningCARef
}
var map_AddOnMeta = map[string]string{
"": "AddOnMeta represents a collection of metadata information for the add-on.",
"displayName": "displayName represents the name of add-on that will be displayed.",
@@ -297,7 +377,7 @@ func (ManagedClusterAddOnList) SwaggerDoc() map[string]string {
var map_ManagedClusterAddOnSpec = map[string]string{
"": "ManagedClusterAddOnSpec defines the install configuration of an addon agent on managed cluster.",
"installNamespace": "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.",
"configs": "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 defautl configurations for add-on. The default is an empty list",
"configs": "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",
}
func (ManagedClusterAddOnSpec) SwaggerDoc() map[string]string {
@@ -336,7 +416,7 @@ func (ObjectReference) SwaggerDoc() map[string]string {
var map_RegistrationConfig = map[string]string{
"": "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.",
"signerName": "signerName is the name of signer that addon agent will use to create csr.",
"subject": "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\": {\n\t\"user\": \"system:open-cluster-management:addon:{addonName}:{clusterName}:{agentName}\",\n\t\"groups: [\"system:open-cluster-management:addon\", \"system:open-cluster-management:addon:{addonName}\", \"system:authenticated\"]\n}",
"subject": "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\": {\n \"user\": \"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}:agent:{agentName}\",\n \"groups: [\"system:open-cluster-management:cluster:{clusterName}:addon:{addonName}\",\n \"system:open-cluster-management:addon:{addonName}\", \"system:authenticated\"]\n}",
}
func (RegistrationConfig) SwaggerDoc() map[string]string {

View File

@@ -13,6 +13,7 @@ import (
type AddonV1alpha1Interface interface {
RESTClient() rest.Interface
AddOnDeploymentConfigsGetter
AddOnTemplatesGetter
ClusterManagementAddOnsGetter
ManagedClusterAddOnsGetter
}
@@ -26,6 +27,10 @@ func (c *AddonV1alpha1Client) AddOnDeploymentConfigs(namespace string) AddOnDepl
return newAddOnDeploymentConfigs(c, namespace)
}
func (c *AddonV1alpha1Client) AddOnTemplates() AddOnTemplateInterface {
return newAddOnTemplates(c)
}
func (c *AddonV1alpha1Client) ClusterManagementAddOns() ClusterManagementAddOnInterface {
return newClusterManagementAddOns(c)
}

View File

@@ -0,0 +1,152 @@
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
"time"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
v1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
scheme "open-cluster-management.io/api/client/addon/clientset/versioned/scheme"
)
// AddOnTemplatesGetter has a method to return a AddOnTemplateInterface.
// A group's client should implement this interface.
type AddOnTemplatesGetter interface {
AddOnTemplates() AddOnTemplateInterface
}
// AddOnTemplateInterface has methods to work with AddOnTemplate resources.
type AddOnTemplateInterface interface {
Create(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.CreateOptions) (*v1alpha1.AddOnTemplate, error)
Update(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.UpdateOptions) (*v1alpha1.AddOnTemplate, 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) (*v1alpha1.AddOnTemplate, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.AddOnTemplateList, 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 *v1alpha1.AddOnTemplate, err error)
AddOnTemplateExpansion
}
// addOnTemplates implements AddOnTemplateInterface
type addOnTemplates struct {
client rest.Interface
}
// newAddOnTemplates returns a AddOnTemplates
func newAddOnTemplates(c *AddonV1alpha1Client) *addOnTemplates {
return &addOnTemplates{
client: c.RESTClient(),
}
}
// Get takes name of the addOnTemplate, and returns the corresponding addOnTemplate object, and an error if there is any.
func (c *addOnTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AddOnTemplate, err error) {
result = &v1alpha1.AddOnTemplate{}
err = c.client.Get().
Resource("addontemplates").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of AddOnTemplates that match those selectors.
func (c *addOnTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AddOnTemplateList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.AddOnTemplateList{}
err = c.client.Get().
Resource("addontemplates").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested addOnTemplates.
func (c *addOnTemplates) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Resource("addontemplates").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a addOnTemplate and creates it. Returns the server's representation of the addOnTemplate, and an error, if there is any.
func (c *addOnTemplates) Create(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.CreateOptions) (result *v1alpha1.AddOnTemplate, err error) {
result = &v1alpha1.AddOnTemplate{}
err = c.client.Post().
Resource("addontemplates").
VersionedParams(&opts, scheme.ParameterCodec).
Body(addOnTemplate).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a addOnTemplate and updates it. Returns the server's representation of the addOnTemplate, and an error, if there is any.
func (c *addOnTemplates) Update(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.UpdateOptions) (result *v1alpha1.AddOnTemplate, err error) {
result = &v1alpha1.AddOnTemplate{}
err = c.client.Put().
Resource("addontemplates").
Name(addOnTemplate.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(addOnTemplate).
Do(ctx).
Into(result)
return
}
// Delete takes name of the addOnTemplate and deletes it. Returns an error if one occurs.
func (c *addOnTemplates) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Resource("addontemplates").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *addOnTemplates) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Resource("addontemplates").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched addOnTemplate.
func (c *addOnTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AddOnTemplate, err error) {
result = &v1alpha1.AddOnTemplate{}
err = c.client.Patch(pt).
Resource("addontemplates").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@@ -16,6 +16,10 @@ func (c *FakeAddonV1alpha1) AddOnDeploymentConfigs(namespace string) v1alpha1.Ad
return &FakeAddOnDeploymentConfigs{c, namespace}
}
func (c *FakeAddonV1alpha1) AddOnTemplates() v1alpha1.AddOnTemplateInterface {
return &FakeAddOnTemplates{c}
}
func (c *FakeAddonV1alpha1) ClusterManagementAddOns() v1alpha1.ClusterManagementAddOnInterface {
return &FakeClusterManagementAddOns{c}
}

View File

@@ -0,0 +1,106 @@
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
)
// FakeAddOnTemplates implements AddOnTemplateInterface
type FakeAddOnTemplates struct {
Fake *FakeAddonV1alpha1
}
var addontemplatesResource = schema.GroupVersionResource{Group: "addon.open-cluster-management.io", Version: "v1alpha1", Resource: "addontemplates"}
var addontemplatesKind = schema.GroupVersionKind{Group: "addon.open-cluster-management.io", Version: "v1alpha1", Kind: "AddOnTemplate"}
// Get takes name of the addOnTemplate, and returns the corresponding addOnTemplate object, and an error if there is any.
func (c *FakeAddOnTemplates) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.AddOnTemplate, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(addontemplatesResource, name), &v1alpha1.AddOnTemplate{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.AddOnTemplate), err
}
// List takes label and field selectors, and returns the list of AddOnTemplates that match those selectors.
func (c *FakeAddOnTemplates) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.AddOnTemplateList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(addontemplatesResource, addontemplatesKind, opts), &v1alpha1.AddOnTemplateList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.AddOnTemplateList{ListMeta: obj.(*v1alpha1.AddOnTemplateList).ListMeta}
for _, item := range obj.(*v1alpha1.AddOnTemplateList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested addOnTemplates.
func (c *FakeAddOnTemplates) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(addontemplatesResource, opts))
}
// Create takes the representation of a addOnTemplate and creates it. Returns the server's representation of the addOnTemplate, and an error, if there is any.
func (c *FakeAddOnTemplates) Create(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.CreateOptions) (result *v1alpha1.AddOnTemplate, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(addontemplatesResource, addOnTemplate), &v1alpha1.AddOnTemplate{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.AddOnTemplate), err
}
// Update takes the representation of a addOnTemplate and updates it. Returns the server's representation of the addOnTemplate, and an error, if there is any.
func (c *FakeAddOnTemplates) Update(ctx context.Context, addOnTemplate *v1alpha1.AddOnTemplate, opts v1.UpdateOptions) (result *v1alpha1.AddOnTemplate, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(addontemplatesResource, addOnTemplate), &v1alpha1.AddOnTemplate{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.AddOnTemplate), err
}
// Delete takes name of the addOnTemplate and deletes it. Returns an error if one occurs.
func (c *FakeAddOnTemplates) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteActionWithOptions(addontemplatesResource, name, opts), &v1alpha1.AddOnTemplate{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeAddOnTemplates) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(addontemplatesResource, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.AddOnTemplateList{})
return err
}
// Patch applies the patch and returns the patched addOnTemplate.
func (c *FakeAddOnTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.AddOnTemplate, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(addontemplatesResource, name, pt, data, subresources...), &v1alpha1.AddOnTemplate{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.AddOnTemplate), err
}

View File

@@ -4,6 +4,8 @@ package v1alpha1
type AddOnDeploymentConfigExpansion interface{}
type AddOnTemplateExpansion interface{}
type ClusterManagementAddOnExpansion interface{}
type ManagedClusterAddOnExpansion interface{}

View File

@@ -0,0 +1,73 @@
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
"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"
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
versioned "open-cluster-management.io/api/client/addon/clientset/versioned"
internalinterfaces "open-cluster-management.io/api/client/addon/informers/externalversions/internalinterfaces"
v1alpha1 "open-cluster-management.io/api/client/addon/listers/addon/v1alpha1"
)
// AddOnTemplateInformer provides access to a shared informer and lister for
// AddOnTemplates.
type AddOnTemplateInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.AddOnTemplateLister
}
type addOnTemplateInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// NewAddOnTemplateInformer constructs a new informer for AddOnTemplate 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 NewAddOnTemplateInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredAddOnTemplateInformer(client, resyncPeriod, indexers, nil)
}
// NewFilteredAddOnTemplateInformer constructs a new informer for AddOnTemplate 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 NewFilteredAddOnTemplateInformer(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.AddonV1alpha1().AddOnTemplates().List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.AddonV1alpha1().AddOnTemplates().Watch(context.TODO(), options)
},
},
&addonv1alpha1.AddOnTemplate{},
resyncPeriod,
indexers,
)
}
func (f *addOnTemplateInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredAddOnTemplateInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *addOnTemplateInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&addonv1alpha1.AddOnTemplate{}, f.defaultInformer)
}
func (f *addOnTemplateInformer) Lister() v1alpha1.AddOnTemplateLister {
return v1alpha1.NewAddOnTemplateLister(f.Informer().GetIndexer())
}

View File

@@ -10,6 +10,8 @@ import (
type Interface interface {
// AddOnDeploymentConfigs returns a AddOnDeploymentConfigInformer.
AddOnDeploymentConfigs() AddOnDeploymentConfigInformer
// AddOnTemplates returns a AddOnTemplateInformer.
AddOnTemplates() AddOnTemplateInformer
// ClusterManagementAddOns returns a ClusterManagementAddOnInformer.
ClusterManagementAddOns() ClusterManagementAddOnInformer
// ManagedClusterAddOns returns a ManagedClusterAddOnInformer.
@@ -32,6 +34,11 @@ func (v *version) AddOnDeploymentConfigs() AddOnDeploymentConfigInformer {
return &addOnDeploymentConfigInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
// AddOnTemplates returns a AddOnTemplateInformer.
func (v *version) AddOnTemplates() AddOnTemplateInformer {
return &addOnTemplateInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
}
// ClusterManagementAddOns returns a ClusterManagementAddOnInformer.
func (v *version) ClusterManagementAddOns() ClusterManagementAddOnInformer {
return &clusterManagementAddOnInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}

View File

@@ -39,6 +39,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
// Group=addon.open-cluster-management.io, Version=v1alpha1
case v1alpha1.SchemeGroupVersion.WithResource("addondeploymentconfigs"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1alpha1().AddOnDeploymentConfigs().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("addontemplates"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1alpha1().AddOnTemplates().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("clustermanagementaddons"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Addon().V1alpha1().ClusterManagementAddOns().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("managedclusteraddons"):

View File

@@ -0,0 +1,52 @@
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
v1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
)
// AddOnTemplateLister helps list AddOnTemplates.
// All objects returned here must be treated as read-only.
type AddOnTemplateLister interface {
// List lists all AddOnTemplates in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.AddOnTemplate, err error)
// Get retrieves the AddOnTemplate from the index for a given name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha1.AddOnTemplate, error)
AddOnTemplateListerExpansion
}
// addOnTemplateLister implements the AddOnTemplateLister interface.
type addOnTemplateLister struct {
indexer cache.Indexer
}
// NewAddOnTemplateLister returns a new AddOnTemplateLister.
func NewAddOnTemplateLister(indexer cache.Indexer) AddOnTemplateLister {
return &addOnTemplateLister{indexer: indexer}
}
// List lists all AddOnTemplates in the indexer.
func (s *addOnTemplateLister) List(selector labels.Selector) (ret []*v1alpha1.AddOnTemplate, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.AddOnTemplate))
})
return ret, err
}
// Get retrieves the AddOnTemplate from the index for a given name.
func (s *addOnTemplateLister) Get(name string) (*v1alpha1.AddOnTemplate, error) {
obj, exists, err := s.indexer.GetByKey(name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("addontemplate"), name)
}
return obj.(*v1alpha1.AddOnTemplate), nil
}

View File

@@ -10,6 +10,10 @@ type AddOnDeploymentConfigListerExpansion interface{}
// AddOnDeploymentConfigNamespaceLister.
type AddOnDeploymentConfigNamespaceListerExpansion interface{}
// AddOnTemplateListerExpansion allows custom methods to be added to
// AddOnTemplateLister.
type AddOnTemplateListerExpansion interface{}
// ClusterManagementAddOnListerExpansion allows custom methods to be added to
// ClusterManagementAddOnLister.
type ClusterManagementAddOnListerExpansion interface{}