Skip to content

Commit

Permalink
Merge pull request #183 from SovereignCloudStack/addons-new
Browse files Browse the repository at this point in the history
✨ Multi-stage cluster addons and hook server
  • Loading branch information
janiskemper authored Jun 28, 2024
2 parents d104052 + 346b8cf commit 22cc6d7
Show file tree
Hide file tree
Showing 386 changed files with 89,178 additions and 111 deletions.
13 changes: 9 additions & 4 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ rules:
min-spaces-from-content: 1

yaml-files:
- '*.yaml'
- '*.yml'
- "*.yaml"
- "*.yml"

ignore:
- '**/vendor/**'
- '.cache'
- "**/vendor/**"
- ".cache"
- _artifacts
- config/crd/**/*.yaml
- config/rbac/**/*.yaml
- config/webhook/**/*.yaml
- test/releases/**
- test/cluster-stacks/**
- .release/**
- .cluster.yaml
- .clusterstack.yaml
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ env-vars-for-wl-cluster:
.PHONY: delete-bootstrap-cluster
delete-bootstrap-cluster: $(CTLPTL) ## Deletes Kind-dev Cluster
$(CTLPTL) delete cluster kind-cso
$(CTLPTL) delete registry cso-registry
$(CTLPTL) delete registry kind-registry

.PHONY: cluster
cluster: get-dependencies $(CTLPTL) $(KUBECTL) ## Creates kind-dev Cluster
Expand Down
1 change: 0 additions & 1 deletion Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ def deploy_capd():
cmd = "curl -sSL {} | {} | kubectl apply -f -".format(capd_uri, envsubst_cmd)
local(cmd, quiet = True)


def prepare_environment():
local("kubectl create namespace cluster --dry-run=client -o yaml | kubectl apply -f -")

Expand Down
98 changes: 98 additions & 0 deletions api/v1alpha1/clusteraddon_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
"github.com/SovereignCloudStack/cluster-stack-operator/pkg/clusteraddon"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
Expand All @@ -27,6 +28,52 @@ const (
ClusterAddonFinalizer = "clusteraddon.clusterstack.x-k8s.io"
)

// StageAnnotation is the annotation name and key for the stage annotation.
const StageAnnotation = "ClusterAddonStage"

// StageAnnotationValue is the value of the stage annotation.
type StageAnnotationValue string

const (
// StageAnnotationValueCreated signifies the stage annotation created.
StageAnnotationValueCreated = StageAnnotationValue("created")
// StageAnnotationValueUpgraded signifies the stage annotation upgraded.
StageAnnotationValueUpgraded = StageAnnotationValue("upgraded")
)

// StagePhase defines the status of helm chart in the cluster addon.
type StagePhase string

var (
// StagePhaseNone signifies the empty stage phase.
StagePhaseNone = StagePhase("")
// StagePhasePending signifies the stage phase 'pending'.
StagePhasePending = StagePhase("Pending")
// StagePhaseWaitingForPreCondition signifies the stage phase 'waitingForPreCondition'.
StagePhaseWaitingForPreCondition = StagePhase("waitingForPreCondition")
// StagePhaseApplyingOrDeleting signifies the stage phase 'applyingOrDeleting'.
StagePhaseApplyingOrDeleting = StagePhase("applyingOrDeleting")
// StagePhaseWaitingForPostCondition signifies the stage phase 'waitingForPostCondition'.
StagePhaseWaitingForPostCondition = StagePhase("waitingForPostCondition")
// StagePhaseDone signifies the stage phase 'done'.
StagePhaseDone = StagePhase("done")
)

// StageStatus represents the helm charts of the hook and it's phases.
type StageStatus struct {
// Name represent name of the helm chart
// +optional
Name string `json:"name"`

// Action is the action of the helm chart. e.g. - apply and delete.
// +optional
Action clusteraddon.Action `json:"action,omitempty"`

// Phase is the current phase of the helm chart.
// +optional
Phase StagePhase `json:"phase"`
}

// ClusterAddonSpec defines the desired state of a ClusterAddon object.
type ClusterAddonSpec struct {
// ClusterStack is the full string <provider>-<name>-<Kubernetes version>-<version> that will be filled with the cluster stack that
Expand All @@ -38,6 +85,10 @@ type ClusterAddonSpec struct {
// +optional
Version string `json:"version,omitempty"`

// Hook specifies the runtime hook for the Cluster event.
// +optional
Hook string `json:"hook,omitempty"`

// ClusterRef is the reference to the clusterv1.Cluster object that corresponds to the workload cluster where this
// controller applies the cluster addons.
ClusterRef *corev1.ObjectReference `json:"clusterRef"`
Expand All @@ -49,6 +100,10 @@ type ClusterAddonStatus struct {
// +optional
Resources []*Resource `json:"resources,omitempty"`

// Stages shows the state of all stages in the current running hook.
// +optional
Stages []StageStatus `json:"stages,omitempty"`

// +optional
// +kubebuilder:default:=false
Ready bool `json:"ready"`
Expand All @@ -61,6 +116,7 @@ type ClusterAddonStatus struct {
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Cluster",type="string",JSONPath=".metadata.ownerReferences[?(@.kind==\"Cluster\")].name"
// +kubebuilder:printcolumn:name="Hook",type="string",JSONPath=".spec.hook",description="Present running hook"
// +kubebuilder:printcolumn:name="Ready",type="boolean",JSONPath=".status.ready"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Time duration since creation of Cluster Addon"
// +kubebuilder:printcolumn:name="Reason",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].reason"
Expand All @@ -76,6 +132,48 @@ type ClusterAddon struct {
Status ClusterAddonStatus `json:"status,omitempty"`
}

// GetStagePhase returns helm chart status for the helm chart.
func (r *ClusterAddon) GetStagePhase(stageName string, action clusteraddon.Action) StagePhase {
for _, stage := range r.Status.Stages {
if stage.Name == stageName && stage.Action == action {
return stage.Phase
}
}

// This cannot occur as we populate phase value with "pending".
return StagePhaseNone
}

// SetStagePhase sets the helm chart status phase.
func (r *ClusterAddon) SetStagePhase(stageName string, action clusteraddon.Action, phase StagePhase) {
for i := range r.Status.Stages {
if r.Status.Stages[i].Name == stageName && r.Status.Stages[i].Action == action {
r.Status.Stages[i].Phase = phase
}
}
}

// SetStageAnnotations sets the annotation whether the cluster got created or upgraded.
func (r *ClusterAddon) SetStageAnnotations(value StageAnnotationValue) {
if r.Annotations == nil {
r.Annotations = make(map[string]string, 0)
}
_, found := r.Annotations[StageAnnotation]
if !found {
r.Annotations[StageAnnotation] = string(value)
}
}

// HasStageAnnotation returns whether the stage annotation exists with a certain value.
func (r *ClusterAddon) HasStageAnnotation(value StageAnnotationValue) bool {
val, found := r.Annotations[StageAnnotation]
if found && val == string(value) {
return true
}

return false
}

// GetConditions returns the observations of the operational state of the ClusterAddon resource.
func (r *ClusterAddon) GetConditions() clusterv1.Conditions {
return r.Status.Conditions
Expand Down
52 changes: 52 additions & 0 deletions api/v1alpha1/conditions_const.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,42 @@ const (
ControlPlaneNotReadyReason = "ControlPlaneNotReady"
)

const (
// EvaluatedCELCondition reports on whether the CEL expression is evaluated properly.
EvaluatedCELCondition clusterv1.ConditionType = "EvaluatedCEL"

// FailedToEvaluatePreConditionReason is used when some pre CEL expression have been failed to evaluate.
FailedToEvaluatePreConditionReason = "FailedToEvaluatePreCondition"

// FailedToEvaluatePostConditionReason is used when some post CEL expression have been failed to evaluate.
FailedToEvaluatePostConditionReason = "FailedToEvaluatePostCondition"
)

const (
// HelmChartFoundCondition reports when mentioned helm chart is present in the cluster addon tar archive.
HelmChartFoundCondition = "HelmChartFound"

// HelmChartMissingReason is used when mentioned helm chart is missing in the cluster addon tar archive.
HelmChartMissingReason = "HelmChartMissing"
)

const (
// HelmChartTemplatedCondition reports on whether the relevant helm chart has been templated properly.
HelmChartTemplatedCondition clusterv1.ConditionType = "HelmChartTemplated"

// TemplateOldClusterStackOverwriteFailedReason is used when old cluster stack overwrite.yaml is wrong.
TemplateOldClusterStackOverwriteFailedReason = "TemplateOldClusterStackOverwriteFailed"

// TemplateOldClusterStackFailedReason is used when there is a issue doing helm template for the old cluster stack.
TemplateOldClusterStackFailedReason = "TemplateOldClusterStackFailed"

// TemplateNewClusterStackOverwriteFailedReason is used when new cluster stack overwrite.yaml is wrong.
TemplateNewClusterStackOverwriteFailedReason = "TemplateNewClusterStackOverwriteFailed"

// TemplateNewClusterStackFailedReason is used when there is a issue doing helm template for the new cluster stack.
TemplateNewClusterStackFailedReason = "TemplateNewClusterStackFailed"
)

const (
// HelmChartAppliedCondition reports on whether the relevant helm chart has been applied.
HelmChartAppliedCondition clusterv1.ConditionType = "HelmChartApplied"
Expand All @@ -37,6 +73,22 @@ const (
ObjectsApplyingOngoingReason = "ObjectsApplyingOngoing"
)

const (
// HookServerReadyCondition reports on whether hook server is ready or not.
HookServerReadyCondition clusterv1.ConditionType = "HookServerReady"

// HookServerUnresponsiveReason is used when hook server don't update the clusterAddon.Spec.Hook.
HookServerUnresponsiveReason = "HookServerUnresponsive"
)

const (
// HelmChartDeletedCondition reports on whether the relevant helm chart has been applied.
HelmChartDeletedCondition clusterv1.ConditionType = "HelmChartDeleted"

// FailedToDeleteObjectsReason is used when some objects have been failed to delete.
FailedToDeleteObjectsReason = "FailedToDeleteObjects"
)

const (
// ProviderClusterStackReleasesSyncedCondition reports on whether the ProviderClusterStackReleases are ready.
ProviderClusterStackReleasesSyncedCondition = "ProviderClusterStackReleasesSynced"
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

Loading

0 comments on commit 22cc6d7

Please sign in to comment.