Skip to content

Commit

Permalink
Introduce ControlPlaneComponent CRD
Browse files Browse the repository at this point in the history
- An instance of this resource will be created for each ControlPlane component to report its status, similar to OC cluster operators.
- Add functionality for components to define their dependencies.
  • Loading branch information
muraee committed Oct 14, 2024
1 parent 5ee1296 commit 819a257
Show file tree
Hide file tree
Showing 68 changed files with 1,333 additions and 139 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ hypershift-api: $(CONTROLLER_GEN)
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..."
rm -rf cmd/install/assets/hypershift-operator/*.yaml
$(CONTROLLER_GEN) $(CRD_OPTIONS) paths="./api/..." output:crd:artifacts:config=cmd/install/assets/hypershift-operator
# TODO: remove when we complete the switch to the new CPO approach.
mv cmd/install/assets/hypershift-operator/hypershift.openshift.io_controlplanecomponents.yaml support/controlplane-component/crds

.PHONY: cluster-api
cluster-api: $(CONTROLLER_GEN)
Expand Down
95 changes: 95 additions & 0 deletions api/hypershift/v1beta1/controlplanecomponent_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package v1beta1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

func init() {
SchemeBuilder.Register(func(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ControlPlaneComponent{},
&ControlPlaneComponentList{},
)
return nil
})
}

const (
// ControlPlaneComponentAvailable indicates whether the ControlPlaneComponent is available.
ControlPlaneComponentAvailable ConditionType = "Available"
// ControlPlaneComponentProgressing indicates whether the ControlPlaneComponent is progressing.
ControlPlaneComponentProgressing ConditionType = "Progressing"

// WaitingForDependenciesReason indicates that there are unavailable dependencies blocking the ControlPlaneComponent reconcilation.
WaitingForDependenciesReason string = "WaitingForDependencies"
// ReconciliationErrorReason indicates that there was an error during the reconcilation of the ControlPlaneComponent.
ReconciliationErrorReason string = "ReconciliationError"
)

// ControlPlaneComponentSpec defines the desired state of ControlPlaneComponent
type ControlPlaneComponentSpec struct {
}

// ComponentResource defines a resource reconciled by a ControlPlaneComponent.
type ComponentResource struct {
// kind is the name of the resource schema.
// +required
Kind string `json:"kind"`

// group is the API group for this resource type.
// +required
Group string `json:"group"`

// name is the name of this resource.
// +required
Name string `json:"name"`
}

// ControlPlaneComponentStatus defines the observed state of ControlPlaneComponent
type ControlPlaneComponentStatus struct {
// version reports the current version of this component.
// +required
Version string `json:"version"`

// resources is a list of the resources reconciled by this component.
// +optional
Resources []ComponentResource `json:"resources,omitempty"`

// Conditions contains details for the current state of the ControlPlane Component.
// If there is an error, then the Available condition will be false.
//
// Current condition types are: "Available"
// +optional
// +listType=map
// +listMapKey=type
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:path=controlplanecomponents,shortName=cpc;cpcs,scope=Namespaced
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version",description="Version"
// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type==\"Available\")].status",description="Available"
// +kubebuilder:printcolumn:name="Progressing",type="string",JSONPath=".status.conditions[?(@.type==\"Progressing\")].status",description="Progressing"
// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type==\"Available\")].message",description="Message"
// +kubebuilder:printcolumn:name="ProgressingMessage",type="string",priority=1,JSONPath=".status.conditions[?(@.type==\"Progressing\")].message",description="ProgressingMessage"
// ControlPlaneComponent specifies the state of a ControlPlane Component
type ControlPlaneComponent struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ControlPlaneComponentSpec `json:"spec,omitempty"`
Status ControlPlaneComponentStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true
// ControlPlaneComponentList contains a list of ControlPlaneComponent
type ControlPlaneComponentList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ControlPlaneComponent `json:"items"`
}
4 changes: 2 additions & 2 deletions api/hypershift/v1beta1/hostedcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ const (
// AWSCredentialsFileSecretKey defines the Kubernetes secret key name that contains
// the customer AWS credentials in the unmanaged authentication strategy for AWS KMS secret encryption
AWSCredentialsFileSecretKey = "credentials"
// ControlPlaneComponent identifies a resource as belonging to a hosted control plane.
ControlPlaneComponent = "hypershift.openshift.io/control-plane-component"
// ControlPlaneComponentLabel identifies a resource as belonging to a hosted control plane.
ControlPlaneComponentLabel = "hypershift.openshift.io/control-plane-component"

// OperatorComponent identifies a component as belonging to the operator.
OperatorComponent = "hypershift.openshift.io/operator-component"
Expand Down
116 changes: 116 additions & 0 deletions api/hypershift/v1beta1/zz_generated.deepcopy.go

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

3 changes: 2 additions & 1 deletion cmd/cluster/core/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func dumpGuestCluster(ctx context.Context, opts *DumpOptions) error {
target := opts.ArtifactDir + "/hostedcluster-" + opts.Name

kubeAPIServerPodList := &corev1.PodList{}
if err := c.List(ctx, kubeAPIServerPodList, client.InNamespace(cpNamespace), client.MatchingLabels{"app": "kube-apiserver", hyperv1.ControlPlaneComponent: "kube-apiserver"}); err != nil {
if err := c.List(ctx, kubeAPIServerPodList, client.InNamespace(cpNamespace), client.MatchingLabels{"app": "kube-apiserver", hyperv1.ControlPlaneComponentLabel: "kube-apiserver"}); err != nil {
return fmt.Errorf("failed to list kube-apiserver pods in control plane namespace: %w", err)
}
var podToForward *corev1.Pod
Expand Down Expand Up @@ -342,6 +342,7 @@ func DumpCluster(ctx context.Context, opts *DumpOptions) error {
&capiv1.Machine{},
&capiv1.MachineSet{},
&hyperv1.HostedControlPlane{},
&hyperv1.ControlPlaneComponent{},
&capiaws.AWSMachine{},
&capiaws.AWSMachineTemplate{},
&capiaws.AWSCluster{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func ReconcileAutoscalerDeployment(deployment *appsv1.Deployment, hcp *hyperv1.H
}

labels := map[string]string{
"app": autoscalerName,
hyperv1.ControlPlaneComponent: autoscalerName,
"app": autoscalerName,
hyperv1.ControlPlaneComponentLabel: autoscalerName,
}
// The selector needs to be invariant for the lifecycle of the project as it's an immutable field,
// otherwise changing would prevent an upgrade from happening.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const (

func selectorLabels() map[string]string {
return map[string]string{
"app": "cloud-credential-operator",
hyperv1.ControlPlaneComponent: "cloud-credential-operator",
"app": "cloud-credential-operator",
hyperv1.ControlPlaneComponentLabel: "cloud-credential-operator",
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,6 @@ func ccmLabels() map[string]string {

func additionalLabels() map[string]string {
return map[string]string{
hyperv1.ControlPlaneComponent: "cloud-controller-manager",
hyperv1.ControlPlaneComponentLabel: "cloud-controller-manager",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,6 @@ func ccmLabels() map[string]string {

func additionalLabels() map[string]string {
return map[string]string{
hyperv1.ControlPlaneComponent: "cloud-controller-manager",
hyperv1.ControlPlaneComponentLabel: "cloud-controller-manager",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func ccmLabels() map[string]string {

func additionalLabels() map[string]string {
return map[string]string{
hyperv1.ControlPlaneComponent: "cloud-controller-manager",
hyperv1.ControlPlaneComponentLabel: "cloud-controller-manager",
config.NeedManagementKASAccessLabel: "true",
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ var (
},
}
clusterPolicyControllerLabels = map[string]string{
"app": "cluster-policy-controller",
hyperv1.ControlPlaneComponent: "cluster-policy-controller",
"app": "cluster-policy-controller",
hyperv1.ControlPlaneComponentLabel: "cluster-policy-controller",
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,9 @@ func ReconcileDeployment(dep *appsv1.Deployment, params Params, platformType hyp
dep.Spec.Template.Labels = map[string]string{}
}
dep.Spec.Template.Labels = map[string]string{
"name": operatorName,
"app": operatorName,
hyperv1.ControlPlaneComponent: operatorName,
"name": operatorName,
"app": operatorName,
hyperv1.ControlPlaneComponentLabel: operatorName,
}

var cnoEnv []corev1.EnvVar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ var (
},
}
hccLabels = map[string]string{
"app": hostedClusterConfigOperatorName,
hyperv1.ControlPlaneComponent: hostedClusterConfigOperatorName,
"app": hostedClusterConfigOperatorName,
hyperv1.ControlPlaneComponentLabel: hostedClusterConfigOperatorName,
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ func cvoLabels() map[string]string {
return map[string]string{
"app": "cluster-version-operator",
// value for compatibility with roks-toolkit clusters
"k8s-app": "cluster-version-operator",
hyperv1.ControlPlaneComponent: "cluster-version-operator",
"k8s-app": "cluster-version-operator",
hyperv1.ControlPlaneComponentLabel: "cluster-version-operator",
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ func NewParams(hcp *hyperv1.HostedControlPlane, version string, releaseImageProv
"target.workload.openshift.io/management": `{"effect": "PreferredDuringScheduling"}`,
}
p.DeploymentConfig.AdditionalLabels = map[string]string{
"name": "dns-operator",
"app": "dns-operator",
hyperv1.ControlPlaneComponent: "dns-operator",
"name": "dns-operator",
"app": "dns-operator",
hyperv1.ControlPlaneComponentLabel: "dns-operator",
}
p.DeploymentConfig.Scheduling.PriorityClass = config.DefaultPriorityClass
if hcp.Annotations[hyperv1.ControlPlanePriorityClass] != "" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func NewEtcdParams(hcp *hyperv1.HostedControlPlane, releaseImageProvider imagepr
if p.DeploymentConfig.AdditionalLabels == nil {
p.DeploymentConfig.AdditionalLabels = make(map[string]string)
}
p.DeploymentConfig.AdditionalLabels[hyperv1.ControlPlaneComponent] = "etcd"
p.DeploymentConfig.AdditionalLabels[hyperv1.ControlPlaneComponentLabel] = "etcd"
p.DeploymentConfig.Scheduling.PriorityClass = config.EtcdPriorityClass
if hcp.Annotations[hyperv1.EtcdPriorityClass] != "" {
p.DeploymentConfig.Scheduling.PriorityClass = hcp.Annotations[hyperv1.EtcdPriorityClass]
Expand Down
Loading

0 comments on commit 819a257

Please sign in to comment.