diff --git a/apis/installer/v1alpha1/hub_cluster_robot_types.go b/apis/installer/v1alpha1/hub_cluster_robot_types.go new file mode 100644 index 00000000..837fb961 --- /dev/null +++ b/apis/installer/v1alpha1/hub_cluster_robot_types.go @@ -0,0 +1,65 @@ +/* +Copyright AppsCode Inc. and Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + ResourceKindHubManagerRobot = "HubManagerRobot" + ResourceHubManagerRobot = "hubmanagerrobot" + ResourceHubManagerRobots = "hubmanagerrobots" +) + +// HubManagerRobot defines the schama for HubManagerRobot. + +// +genclient +// +genclient:skipVerbs=updateStatus +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=hubmanagerrobots,singular=hubmanagerrobot,categories={kubeops,appscode} +type HubManagerRobot struct { + metav1.TypeMeta `json:",inline,omitempty"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec HubManagerRobotSpec `json:"spec,omitempty"` +} + +// HubManagerRobotSpec is the schema for Identity Server values file +type HubManagerRobotSpec struct { + //+optional + NameOverride string `json:"nameOverride"` + //+optional + FullnameOverride string `json:"fullnameOverride"` + // +optional + KubeconfigSecretName string `json:"kubeconfigSecretName"` + // +optional + AddonManagerNamespace string `json:"addonManagerNamespace"` + Kubectl DockerImage `json:"kubectl"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// HubManagerRobotList is a list of HubManagerRobots +type HubManagerRobotList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + // Items is a list of HubManagerRobot CRD objects + Items []HubManagerRobot `json:"items,omitempty"` +} diff --git a/apis/installer/v1alpha1/register.go b/apis/installer/v1alpha1/register.go index c3251ed9..ac1faf15 100644 --- a/apis/installer/v1alpha1/register.go +++ b/apis/installer/v1alpha1/register.go @@ -61,6 +61,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &ClusterManagerHubList{}, &ClusterManagerSpoke{}, &ClusterManagerSpokeList{}, + &HubManagerRobot{}, + &HubManagerRobotList{}, ) scheme.AddKnownTypes(SchemeGroupVersion, diff --git a/apis/installer/v1alpha1/zz_generated.deepcopy.go b/apis/installer/v1alpha1/zz_generated.deepcopy.go index d8eafd27..9309da4b 100644 --- a/apis/installer/v1alpha1/zz_generated.deepcopy.go +++ b/apis/installer/v1alpha1/zz_generated.deepcopy.go @@ -571,6 +571,80 @@ func (in *HubInfo) DeepCopy() *HubInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HubManagerRobot) DeepCopyInto(out *HubManagerRobot) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubManagerRobot. +func (in *HubManagerRobot) DeepCopy() *HubManagerRobot { + if in == nil { + return nil + } + out := new(HubManagerRobot) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HubManagerRobot) 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 *HubManagerRobotList) DeepCopyInto(out *HubManagerRobotList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]HubManagerRobot, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubManagerRobotList. +func (in *HubManagerRobotList) DeepCopy() *HubManagerRobotList { + if in == nil { + return nil + } + out := new(HubManagerRobotList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HubManagerRobotList) 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 *HubManagerRobotSpec) DeepCopyInto(out *HubManagerRobotSpec) { + *out = *in + out.Kubectl = in.Kubectl +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubManagerRobotSpec. +func (in *HubManagerRobotSpec) DeepCopy() *HubManagerRobotSpec { + if in == nil { + return nil + } + out := new(HubManagerRobotSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImageRef) DeepCopyInto(out *ImageRef) { *out = *in diff --git a/charts/hub-cluster-robot/Chart.yaml b/charts/hub-cluster-robot/Chart.yaml new file mode 100644 index 00000000..8bbff164 --- /dev/null +++ b/charts/hub-cluster-robot/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +description: Hub Cluster Robot +name: hub-cluster-robot +version: v2024.8.9 +appVersion: v0.0.1 +home: https://github.com/kluster-manager/cluster-auth +icon: https://cdn.appscode.com/images/products/searchlight/icons/android-icon-192x192.png +sources: +- https://github.com/kluster-manager/cluster-auth +maintainers: +- name: appscode + email: support@appscode.com diff --git a/charts/hub-cluster-robot/README.md b/charts/hub-cluster-robot/README.md new file mode 100644 index 00000000..3b7fc8cd --- /dev/null +++ b/charts/hub-cluster-robot/README.md @@ -0,0 +1,68 @@ +# Hub Cluster Robot + +[Hub Cluster Robot](https://github.com/kluster-manager) - Hub Cluster Robot + +## TL;DR; + +```bash +$ helm repo add appscode https://charts.appscode.com/stable +$ helm repo update +$ helm search repo appscode/hub-cluster-robot --version=v2024.8.9 +$ helm upgrade -i hub-cluster-robot appscode/hub-cluster-robot -n open-cluster-management --create-namespace --version=v2024.8.9 +``` + +## Introduction + +This chart deploys a Hub Cluster Robot on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.21+ + +## Installing the Chart + +To install/upgrade the chart with the release name `hub-cluster-robot`: + +```bash +$ helm upgrade -i hub-cluster-robot appscode/hub-cluster-robot -n open-cluster-management --create-namespace --version=v2024.8.9 +``` + +The command deploys a Hub Cluster Robot on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall the `hub-cluster-robot`: + +```bash +$ helm uninstall hub-cluster-robot -n open-cluster-management +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the `hub-cluster-robot` chart and their default values. + +| Parameter | Description | Default | +|-----------------------|-------------|----------------------------------------------------| +| nameOverride | | "" | +| fullnameOverride | | "" | +| kubeconfigSecretName | | "" | +| addonManagerNamespace | | open-cluster-management-cluster-auth | +| kubectl.image | | ghcr.io/appscode/kubectl-nonroot:1.25 | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm upgrade -i`. For example: + +```bash +$ helm upgrade -i hub-cluster-robot appscode/hub-cluster-robot -n open-cluster-management --create-namespace --version=v2024.8.9 --set addonManagerNamespace=open-cluster-management-cluster-auth +``` + +Alternatively, a YAML file that specifies the values for the parameters can be provided while +installing the chart. For example: + +```bash +$ helm upgrade -i hub-cluster-robot appscode/hub-cluster-robot -n open-cluster-management --create-namespace --version=v2024.8.9 --values values.yaml +``` diff --git a/charts/hub-cluster-robot/common/rbac/cluster_role.yaml b/charts/hub-cluster-robot/common/rbac/cluster_role.yaml new file mode 100644 index 00000000..3c588d2f --- /dev/null +++ b/charts/hub-cluster-robot/common/rbac/cluster_role.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: open-cluster-management:hub-cluster-robot:cluster-auth +rules: + - apiGroups: [""] + resources: ["secrets", "serviceaccounts"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "authentication.k8s.appscode.com" ] + resources: [ "*" ] + verbs: [ "*" ] diff --git a/charts/hub-cluster-robot/common/rbac/role_binding.yaml b/charts/hub-cluster-robot/common/rbac/role_binding.yaml new file mode 100644 index 00000000..524e2fd4 --- /dev/null +++ b/charts/hub-cluster-robot/common/rbac/role_binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: open-cluster-management:hub-cluster-robot:cluster-auth + namespace: open-cluster-management-cluster-auth +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: open-cluster-management:hub-cluster-robot +subjects: + - kind: ServiceAccount + name: hub-cluster-robot + namespace: {{ .Release.Namespace }} diff --git a/charts/hub-cluster-robot/common/rbac/service_account.yaml b/charts/hub-cluster-robot/common/rbac/service_account.yaml new file mode 100644 index 00000000..77a18c6a --- /dev/null +++ b/charts/hub-cluster-robot/common/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: hub-cluster-robot + namespace: {{ .Release.Namespace }} diff --git a/charts/hub-cluster-robot/doc.yaml b/charts/hub-cluster-robot/doc.yaml new file mode 100644 index 00000000..df0c4e73 --- /dev/null +++ b/charts/hub-cluster-robot/doc.yaml @@ -0,0 +1,18 @@ +project: + name: Hub Cluster Robot + shortName: Hub Cluster Robot + url: https://github.com/kluster-manager + description: Hub Cluster Robot + app: a Hub Cluster Robot +repository: + url: https://charts.appscode.com/stable + name: appscode +chart: + name: hub-cluster-robot + values: -- generate from values file -- + valuesExample: -- generate from values file -- +prerequisites: +- Kubernetes 1.21+ +release: + name: hub-cluster-robot + namespace: open-cluster-management diff --git a/charts/hub-cluster-robot/templates/_helpers.tpl b/charts/hub-cluster-robot/templates/_helpers.tpl new file mode 100644 index 00000000..806506c9 --- /dev/null +++ b/charts/hub-cluster-robot/templates/_helpers.tpl @@ -0,0 +1,69 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "hub-cluster-robot.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "hub-cluster-robot.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "hub-cluster-robot.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hub-cluster-robot.labels" -}} +helm.sh/chart: {{ include "hub-cluster-robot.chart" . }} +{{ include "hub-cluster-robot.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hub-cluster-robot.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hub-cluster-robot.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "hub-cluster-robot.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "hub-cluster-robot.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Addon manager namespace +*/}} +{{- define "hub-cluster-robot.namespace" -}} +{{ ternary .Release.Namespace (required "A valid .Values.addonManagerNamespace is required!" .Values.addonManagerNamespace) (empty .Values.kubeconfigSecretName) }} +{{- end }} diff --git a/charts/hub-cluster-robot/templates/k8s/addon.yaml b/charts/hub-cluster-robot/templates/k8s/addon.yaml new file mode 100644 index 00000000..0019a134 --- /dev/null +++ b/charts/hub-cluster-robot/templates/k8s/addon.yaml @@ -0,0 +1,12 @@ +{{- if not .Values.kubeconfigSecretName }} + +{{- $restpl := $.Files.Get "common/rbac/service_account.yaml" }} +{{ tpl $restpl $ }} +--- +{{- $restpl := $.Files.Get "common/rbac/cluster_role.yaml" }} +{{ tpl $restpl $ }} +--- +{{- $restpl := $.Files.Get "common/rbac/role_binding.yaml" }} +{{ tpl $restpl $ }} + +{{- end }} diff --git a/charts/hub-cluster-robot/templates/ocm-mc/addon.yaml b/charts/hub-cluster-robot/templates/ocm-mc/addon.yaml new file mode 100644 index 00000000..150e7d9e --- /dev/null +++ b/charts/hub-cluster-robot/templates/ocm-mc/addon.yaml @@ -0,0 +1,49 @@ +{{- if .Values.kubeconfigSecretName }} + +apiVersion: batch/v1 +kind: Job +metadata: + name: cluster-auth-configure-addon + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook-weight": "2" + "helm.sh/hook": post-install,post-upgrade,post-rollback + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + ttlSecondsAfterFinished: 0 + backoffLimit: 3 + template: + spec: + automountServiceAccountToken: false + containers: + - name: kubectl + image: {{ .Values.kubectl.image }} + workingDir: /var/run/secrets/ocm + command: + - sh + - -c + - | + sleep 2; \ + kubectl --kubeconfig=auth/kubeconfig create ns {{ include "hub-cluster-robot.namespace" $ }} || true; \ + kubectl --kubeconfig=auth/kubeconfig apply -f - <