Skip to content

Commit f6340bb

Browse files
✨ allow installing and uninstalling hub-addons (#50)
* feat: allow installing and uninstalling hub-addons Signed-off-by: Artur Shad Nik <arturshadnik@gmail.com> * chore: typo Signed-off-by: Artur Shad Nik <arturshadnik@gmail.com> * chore: Apply suggestions from code review Co-authored-by: Tyler Gillson <tyler.gillson@gmail.com> Signed-off-by: Artur Shad Nik <arturshadnik@gmail.com> --------- Signed-off-by: Artur Shad Nik <arturshadnik@gmail.com> Co-authored-by: Tyler Gillson <tyler.gillson@gmail.com>
1 parent 83e94aa commit f6340bb

File tree

11 files changed

+311
-8
lines changed

11 files changed

+311
-8
lines changed

fleetconfig-controller/api/v1alpha1/fleetconfig_types.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ type FleetConfigSpec struct {
6161

6262
// FleetConfigStatus defines the observed state of FleetConfig.
6363
type FleetConfigStatus struct {
64-
Phase string `json:"phase,omitempty"`
65-
Conditions []Condition `json:"conditions,omitempty"`
66-
JoinedSpokes []JoinedSpoke `json:"joinedSpokes,omitempty"`
64+
Phase string `json:"phase,omitempty"`
65+
Conditions []Condition `json:"conditions,omitempty"`
66+
JoinedSpokes []JoinedSpoke `json:"joinedSpokes,omitempty"`
67+
InstalledHubAddOns []InstalledHubAddOn `json:"installedHubAddOns,omitempty"`
6768
}
6869

6970
// ToComparable returns a deep copy of the FleetConfigStatus that's suitable for semantic comparison.
@@ -488,6 +489,18 @@ func (j *JoinedSpoke) conditionName(c int) string {
488489
return name
489490
}
490491

492+
// InstalledHubAddOn tracks metadata for each hubAddon that is successfully installed on the hub.
493+
type InstalledHubAddOn struct {
494+
// BundleVersion is the bundle version used when installing the addon.
495+
BundleVersion string `json:"bundleVersion"`
496+
497+
// Name is the name of the addon.
498+
Name string `json:"name"`
499+
500+
// Namespace is the namespace that the addon was installed into.
501+
Namespace string `json:"namespace,omitempty"`
502+
}
503+
491504
// Klusterlet is the configuration for a klusterlet.
492505
type Klusterlet struct {
493506
// Annotations to apply to the spoke cluster. If not present, the 'agent.open-cluster-management.io/' prefix is added to each key.

fleetconfig-controller/api/v1alpha1/validation.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ func allowFleetConfigUpdate(newObject *FleetConfig, oldObject *FleetConfig) erro
8484
// checks that each addOnConfig specifies a valid source of manifests
8585
func validateAddonConfigs(ctx context.Context, client client.Client, oldObject, newObject *FleetConfig) field.ErrorList {
8686
errs := field.ErrorList{}
87+
88+
// Validate that AddOnConfig names are unique within the AddOnConfigs list
89+
addOnConfigNames := make(map[string]int)
90+
for i, a := range newObject.Spec.AddOnConfigs {
91+
key := fmt.Sprintf("%s-%s", a.Name, a.Version)
92+
if existingIndex, found := addOnConfigNames[key]; found {
93+
errs = append(errs, field.Invalid(field.NewPath("addOnConfigs").Index(i), key,
94+
fmt.Sprintf("duplicate addOnConfig %s (name-version) found at indices %d and %d", key, existingIndex, i)))
95+
} else {
96+
addOnConfigNames[key] = i
97+
}
98+
}
99+
87100
for i, a := range newObject.Spec.AddOnConfigs {
88101
cm := corev1.ConfigMap{}
89102
cmName := fmt.Sprintf("%s-%s-%s", AddonConfigMapNamePrefix, a.Name, a.Version)
@@ -172,7 +185,7 @@ func validateAddons(newObject *FleetConfig) field.ErrorList {
172185
for i, s := range newObject.Spec.Spokes {
173186
for j, a := range s.AddOns {
174187
if !configuredAddons[a.ConfigName] {
175-
errs = append(errs, field.Invalid(field.NewPath("Spokes").Index(i).Child("AddOns").Index(j), a.ConfigName, fmt.Sprintf("cannot enable addon %s for spoke %s, no configuration found in spec.AddOnConfigs", a.ConfigName, s.Name)))
188+
errs = append(errs, field.Invalid(field.NewPath("Spokes").Index(i).Child("AddOns").Index(j), a.ConfigName, fmt.Sprintf("cannot enable addon %s for spoke %s, no configuration found in spec.AddOnConfigs or spec.HubAddOns", a.ConfigName, s.Name)))
176189
}
177190
}
178191
}
@@ -192,8 +205,19 @@ func validateHubAddons(ctx context.Context, oldObject, newObject *FleetConfig) f
192205

193206
for i, ha := range newObject.Spec.HubAddOns {
194207
if _, found := addOnConfigNames[ha.Name]; found {
195-
errs = append(errs, field.Invalid(field.NewPath("hubAddOn").Index(i), ha.Name,
196-
fmt.Sprintf("hubAddOn name %s clashes with an existing addOnConfig name", ha.Name)))
208+
errs = append(errs, field.Invalid(field.NewPath("hubAddOns").Index(i), ha.Name,
209+
fmt.Sprintf("hubAddOn name %s clashes with an existing addOnConfig name.", ha.Name)))
210+
}
211+
}
212+
213+
// Validate that HubAddOn names are unique within the HubAddOns list
214+
hubAddOnNames := make(map[string]int)
215+
for i, ha := range newObject.Spec.HubAddOns {
216+
if existingIndex, found := hubAddOnNames[ha.Name]; found {
217+
errs = append(errs, field.Invalid(field.NewPath("hubAddOns").Index(i), ha.Name,
218+
fmt.Sprintf("duplicate hubAddOn name %s found at indices %d and %d", ha.Name, existingIndex, i)))
219+
} else {
220+
hubAddOnNames[ha.Name] = i
197221
}
198222
}
199223

fleetconfig-controller/api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fleetconfig-controller/charts/fleetconfig-controller/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Resource specifications for all klusterlet-managed containers.
8181
| `fleetConfig.registrationAuth.hubClusterARN` | The ARN of the hub cluster. This is only required if configuring an EKS FleetConfig. Example: "arn:aws:eks:us-west-2:<HUB_AWS_ACCOUNT_ID>:cluster/<HUB_CLUSTER_NAME>". | `""` |
8282
| `fleetConfig.registrationAuth.autoApprovedARNPatterns` | Optional list of spoke cluster name ARN patterns that the hub will auto-approve. | `[]` |
8383
| `fleetConfig.hub.addOnConfigs` | Global add-on configuration for the hub cluster. | `[]` |
84+
| `fleetConfig.hub.hubAddOns` | Built-in add-on configuration for the hub cluster. | `[]` |
8485
| `fleetConfig.hub.clusterManager.enabled` | Whether to enable the cluster manager. Set to false if using Singleton Control Plane. | `true` |
8586
| `fleetConfig.hub.clusterManager.featureGates.DefaultClusterSet` | DefaultClusterSet feature gate. | `true` |
8687
| `fleetConfig.hub.clusterManager.featureGates.ManifestWorkReplicaSet` | ManifestWorkReplicaSet feature gate. | `true` |

fleetconfig-controller/charts/fleetconfig-controller/crds/fleetconfig.open-cluster-management.io-crds.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,6 +2668,27 @@ spec:
26682668
- wantStatus
26692669
type: object
26702670
type: array
2671+
installedHubAddOns:
2672+
items:
2673+
description: InstalledHubAddOn tracks metadata for each hubAddon
2674+
that is successfully installed on the hub.
2675+
properties:
2676+
bundleVersion:
2677+
description: BundleVersion is the bundle version used when installing
2678+
the addon.
2679+
type: string
2680+
name:
2681+
description: Name is the name of the addon.
2682+
type: string
2683+
namespace:
2684+
description: Namespace is the namespace that the addon was installed
2685+
into.
2686+
type: string
2687+
required:
2688+
- bundleVersion
2689+
- name
2690+
type: object
2691+
type: array
26712692
joinedSpokes:
26722693
items:
26732694
description: JoinedSpoke represents a spoke that has been joined

fleetconfig-controller/charts/fleetconfig-controller/templates/fleetconfig.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,5 @@ spec:
111111
overwrite: {{ .overwrite }}
112112
{{- end }}
113113
{{- end }}
114+
hubAddOns: {{- toYaml .Values.fleetConfig.hub.hubAddOns | nindent 4 }}
114115
{{- end }}

fleetconfig-controller/charts/fleetconfig-controller/templates/rbac/manager-rbac.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ rules:
137137
- "addonplacementscores"
138138
- "managedclustersetbindings"
139139
- "placements"
140-
verbs: ["get", "list", "watch"]
140+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
141141
- apiGroups: ["cluster.open-cluster-management.io"]
142142
resources:
143143
- "managedclusters/status"

fleetconfig-controller/charts/fleetconfig-controller/values.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ fleetConfig:
6868
# clusterRoleBinding: "" # ClusterRoleBinding to apply to the add-on.
6969
# hubRegistration: false # Enable the agent to register to the hub cluster.
7070
# overwrite: false # Whether to overwrite the add-on if it already exists.
71+
## @param fleetConfig.hub.hubAddOns Built-in add-on configuration for the hub cluster.
72+
hubAddOns: []
73+
# - name: "" # Name of the add-on. Must be one of "argocd", "governance-policy-framework"
74+
# installNamespace: "" # Namespace to install the add-on. Not applicable for "argocd" add-on. For "governance-policy-framework" add-on, if not set, defaults to "open-cluster-management" namespace.
75+
# createNamespace: false # Whether to create the namespace for the add-on.
7176
## Configuration for the Cluster Manager on the Hub cluster.
7277
clusterManager:
7378
## @descriptionStart

fleetconfig-controller/config/crd/bases/fleetconfig.open-cluster-management.io_fleetconfigs.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,6 +2658,27 @@ spec:
26582658
- wantStatus
26592659
type: object
26602660
type: array
2661+
installedHubAddOns:
2662+
items:
2663+
description: InstalledHubAddOn tracks metadata for each hubAddon
2664+
that is successfully installed on the hub.
2665+
properties:
2666+
bundleVersion:
2667+
description: BundleVersion is the bundle version used when installing
2668+
the addon.
2669+
type: string
2670+
name:
2671+
description: Name is the name of the addon.
2672+
type: string
2673+
namespace:
2674+
description: Namespace is the namespace that the addon was installed
2675+
into.
2676+
type: string
2677+
required:
2678+
- bundleVersion
2679+
- name
2680+
type: object
2681+
type: array
26612682
joinedSpokes:
26622683
items:
26632684
description: JoinedSpoke represents a spoke that has been joined

0 commit comments

Comments
 (0)