Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions fleetconfig-controller/api/v1alpha1/fleetconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ type FleetConfigSpec struct {

// FleetConfigStatus defines the observed state of FleetConfig.
type FleetConfigStatus struct {
Phase string `json:"phase,omitempty"`
Conditions []Condition `json:"conditions,omitempty"`
JoinedSpokes []JoinedSpoke `json:"joinedSpokes,omitempty"`
Phase string `json:"phase,omitempty"`
Conditions []Condition `json:"conditions,omitempty"`
JoinedSpokes []JoinedSpoke `json:"joinedSpokes,omitempty"`
InstalledHubAddOns []InstalledHubAddOn `json:"installedHubAddOns,omitempty"`
}

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

// InstalledHubAddOn tracks metadata for each hubAddon that is successfully installed on the hub.
type InstalledHubAddOn struct {
// BundleVersion is the bundle version used when installing the addon.
BundleVersion string `json:"bundleVersion"`

// Name is the name of the addon.
Name string `json:"name"`

// Namespace is the namespace that the addon was installed into.
Namespace string `json:"namespace,omitempty"`
}

// Klusterlet is the configuration for a klusterlet.
type Klusterlet struct {
// Annotations to apply to the spoke cluster. If not present, the 'agent.open-cluster-management.io/' prefix is added to each key.
Expand Down
30 changes: 27 additions & 3 deletions fleetconfig-controller/api/v1alpha1/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ func allowFleetConfigUpdate(newObject *FleetConfig, oldObject *FleetConfig) erro
// checks that each addOnConfig specifies a valid source of manifests
func validateAddonConfigs(ctx context.Context, client client.Client, oldObject, newObject *FleetConfig) field.ErrorList {
errs := field.ErrorList{}

// Validate that AddOnConfig names are unique within the AddOnConfigs list
addOnConfigNames := make(map[string]int)
for i, a := range newObject.Spec.AddOnConfigs {
key := fmt.Sprintf("%s-%s", a.Name, a.Version)
if existingIndex, found := addOnConfigNames[key]; found {
errs = append(errs, field.Invalid(field.NewPath("addOnConfigs").Index(i), key,
fmt.Sprintf("duplicate addOnConfig %s (name-version) found at indices %d and %d", key, existingIndex, i)))
} else {
addOnConfigNames[key] = i
}
}

for i, a := range newObject.Spec.AddOnConfigs {
cm := corev1.ConfigMap{}
cmName := fmt.Sprintf("%s-%s-%s", AddonConfigMapNamePrefix, a.Name, a.Version)
Expand Down Expand Up @@ -172,7 +185,7 @@ func validateAddons(newObject *FleetConfig) field.ErrorList {
for i, s := range newObject.Spec.Spokes {
for j, a := range s.AddOns {
if !configuredAddons[a.ConfigName] {
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)))
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)))
}
}
}
Expand All @@ -192,8 +205,19 @@ func validateHubAddons(ctx context.Context, oldObject, newObject *FleetConfig) f

for i, ha := range newObject.Spec.HubAddOns {
if _, found := addOnConfigNames[ha.Name]; found {
errs = append(errs, field.Invalid(field.NewPath("hubAddOn").Index(i), ha.Name,
fmt.Sprintf("hubAddOn name %s clashes with an existing addOnConfig name", ha.Name)))
errs = append(errs, field.Invalid(field.NewPath("hubAddOns").Index(i), ha.Name,
fmt.Sprintf("hubAddOn name %s clashes with an existing addOnConfig name.", ha.Name)))
}
}

// Validate that HubAddOn names are unique within the HubAddOns list
hubAddOnNames := make(map[string]int)
for i, ha := range newObject.Spec.HubAddOns {
if existingIndex, found := hubAddOnNames[ha.Name]; found {
errs = append(errs, field.Invalid(field.NewPath("hubAddOns").Index(i), ha.Name,
fmt.Sprintf("duplicate hubAddOn name %s found at indices %d and %d", ha.Name, existingIndex, i)))
} else {
hubAddOnNames[ha.Name] = i
}
}

Expand Down
20 changes: 20 additions & 0 deletions fleetconfig-controller/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Resource specifications for all klusterlet-managed containers.
| `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>". | `""` |
| `fleetConfig.registrationAuth.autoApprovedARNPatterns` | Optional list of spoke cluster name ARN patterns that the hub will auto-approve. | `[]` |
| `fleetConfig.hub.addOnConfigs` | Global add-on configuration for the hub cluster. | `[]` |
| `fleetConfig.hub.hubAddOns` | Built-in add-on configuration for the hub cluster. | `[]` |
| `fleetConfig.hub.clusterManager.enabled` | Whether to enable the cluster manager. Set to false if using Singleton Control Plane. | `true` |
| `fleetConfig.hub.clusterManager.featureGates.DefaultClusterSet` | DefaultClusterSet feature gate. | `true` |
| `fleetConfig.hub.clusterManager.featureGates.ManifestWorkReplicaSet` | ManifestWorkReplicaSet feature gate. | `true` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2668,6 +2668,27 @@ spec:
- wantStatus
type: object
type: array
installedHubAddOns:
items:
description: InstalledHubAddOn tracks metadata for each hubAddon
that is successfully installed on the hub.
properties:
bundleVersion:
description: BundleVersion is the bundle version used when installing
the addon.
type: string
name:
description: Name is the name of the addon.
type: string
namespace:
description: Namespace is the namespace that the addon was installed
into.
type: string
required:
- bundleVersion
- name
type: object
type: array
joinedSpokes:
items:
description: JoinedSpoke represents a spoke that has been joined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,5 @@ spec:
overwrite: {{ .overwrite }}
{{- end }}
{{- end }}
hubAddOns: {{- toYaml .Values.fleetConfig.hub.hubAddOns | nindent 4 }}
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ rules:
- "addonplacementscores"
- "managedclustersetbindings"
- "placements"
verbs: ["get", "list", "watch"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["cluster.open-cluster-management.io"]
resources:
- "managedclusters/status"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ fleetConfig:
# clusterRoleBinding: "" # ClusterRoleBinding to apply to the add-on.
# hubRegistration: false # Enable the agent to register to the hub cluster.
# overwrite: false # Whether to overwrite the add-on if it already exists.
## @param fleetConfig.hub.hubAddOns Built-in add-on configuration for the hub cluster.
hubAddOns: []
# - name: "" # Name of the add-on. Must be one of "argocd", "governance-policy-framework"
# 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.
# createNamespace: false # Whether to create the namespace for the add-on.
## Configuration for the Cluster Manager on the Hub cluster.
clusterManager:
## @descriptionStart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2658,6 +2658,27 @@ spec:
- wantStatus
type: object
type: array
installedHubAddOns:
items:
description: InstalledHubAddOn tracks metadata for each hubAddon
that is successfully installed on the hub.
properties:
bundleVersion:
description: BundleVersion is the bundle version used when installing
the addon.
type: string
name:
description: Name is the name of the addon.
type: string
namespace:
description: Namespace is the namespace that the addon was installed
into.
type: string
required:
- bundleVersion
- name
type: object
type: array
joinedSpokes:
items:
description: JoinedSpoke represents a spoke that has been joined
Expand Down
Loading
Loading