Skip to content

Commit

Permalink
chore(lifecycle-operator): introduce v1beta1 lifecycle API (#2640)
Browse files Browse the repository at this point in the history
Signed-off-by: Griffin <[email protected]>
Signed-off-by: Prakriti Mandal <[email protected]>
Co-authored-by: Florian Bacher <[email protected]>
  • Loading branch information
prakrit55 and bacherfl authored Dec 21, 2023
1 parent 370bd22 commit 11b7ea2
Show file tree
Hide file tree
Showing 68 changed files with 23,855 additions and 986 deletions.
3,558 changes: 3,176 additions & 382 deletions .github/scripts/.helm-tests/default/result.yaml

Large diffs are not rendered by default.

3,386 changes: 3,090 additions & 296 deletions .github/scripts/.helm-tests/lifecycle-only/result.yaml

Large diffs are not rendered by default.

3,386 changes: 3,090 additions & 296 deletions .github/scripts/.helm-tests/lifecycle-with-certs/result.yaml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions lifecycle-operator/PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,80 @@ resources:
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1alpha4
version: v1alpha4
version: "3"
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnApp
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnAppVersion
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnEvaluation
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnEvaluationDefinition
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnTask
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnTaskDefinition
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
webhooks:
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnWorkload
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: keptn.sh
group: lifecycle
kind: KeptnAppCreationRequest
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: keptn.sh
group: lifecycle
kind: KeptnWorkloadVersion
path: github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/lifecycle/v1beta1
version: v1beta1
version: "3"
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type KeptnAppCreationRequestSpec struct {

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:storageversion

// KeptnAppCreationRequest is the Schema for the keptnappcreationrequests API
type KeptnAppCreationRequest struct {
Expand Down
214 changes: 214 additions & 0 deletions lifecycle-operator/apis/lifecycle/v1beta1/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
package common

import (
"crypto/sha256"
"encoding/hex"
"errors"
"math/rand"
"strconv"

operatorcommon "github.com/keptn/lifecycle-toolkit/lifecycle-operator/common"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const WorkloadAnnotation = "keptn.sh/workload"
const VersionAnnotation = "keptn.sh/version"
const AppAnnotation = "keptn.sh/app"
const PreDeploymentTaskAnnotation = "keptn.sh/pre-deployment-tasks"
const PostDeploymentTaskAnnotation = "keptn.sh/post-deployment-tasks"
const K8sRecommendedWorkloadAnnotations = "app.kubernetes.io/name"
const K8sRecommendedVersionAnnotations = "app.kubernetes.io/version"
const K8sRecommendedAppAnnotations = "app.kubernetes.io/part-of"
const K8sRecommendedManagedByAnnotations = "app.kubernetes.io/managed-by"
const PreDeploymentEvaluationAnnotation = "keptn.sh/pre-deployment-evaluations"
const PostDeploymentEvaluationAnnotation = "keptn.sh/post-deployment-evaluations"
const SchedulingGateRemoved = "keptn.sh/scheduling-gate-removed"
const TaskNameAnnotation = "keptn.sh/task-name"
const NamespaceEnabledAnnotation = "keptn.sh/lifecycle-toolkit"
const CreateAppTaskSpanName = "create_%s_app_task"
const CreateWorkloadTaskSpanName = "create_%s_deployment_task"
const CreateAppEvalSpanName = "create_%s_app_evaluation"
const CreateWorkloadEvalSpanName = "create_%s_deployment_evaluation"
const AppTypeAnnotation = "keptn.sh/app-type"
const KeptnGate = "keptn-prechecks-gate"
const ContainerNameAnnotation = "keptn.sh/container"

const MinKeptnNameLen = 80
const MaxK8sObjectLength = 253

var ErrCannotCastKeptnAppVersion = errors.New("cannot cast KeptnAppVersion to v1alpha3")
var ErrCannotCastKeptnApp = errors.New("cannot cast KeptnApp to v1alpha3")

type AppType string

const (
AppTypeSingleService AppType = "single-service"
AppTypeMultiService AppType = "multi-service"
)

// KeptnState is a string containing current Phase state (Progressing/Succeeded/Failed/Unknown/Pending/Cancelled)
type KeptnState string

const (
StateProgressing KeptnState = "Progressing"
StateSucceeded KeptnState = "Succeeded"
StateFailed KeptnState = "Failed"
StateUnknown KeptnState = "Unknown"
StatePending KeptnState = "Pending"
StateDeprecated KeptnState = "Deprecated"
// Deprecated: Use StateDeprecated instead. Should only be used in checks for backwards compatibility reasons
)

func (k KeptnState) IsCompleted() bool {
return k == StateSucceeded || k == StateFailed || k == StateDeprecated
}

func (k KeptnState) IsSucceeded() bool {
return k == StateSucceeded
}

func (k KeptnState) IsFailed() bool {
return k == StateFailed
}

func (k KeptnState) IsDeprecated() bool {
return k == StateDeprecated
}

func (k KeptnState) IsPending() bool {
return k == StatePending
}

type StatusSummary struct {
Total int
Progressing int
Failed int
Succeeded int
Pending int
Unknown int
Deprecated int
}

func UpdateStatusSummary(status KeptnState, summary StatusSummary) StatusSummary {
switch status {
case StateFailed:
summary.Failed++
case StateDeprecated:
summary.Deprecated++
case StateSucceeded:
summary.Succeeded++
case StateProgressing:
summary.Progressing++
case StatePending, "":
summary.Pending++
case StateUnknown:
summary.Unknown++
}
return summary
}

func (s StatusSummary) GetTotalCount() int {
return s.Failed + s.Succeeded + s.Progressing + s.Pending + s.Unknown + s.Deprecated
}

func GetOverallState(s StatusSummary) KeptnState {
if s.Failed > 0 || s.Deprecated > 0 {
return StateFailed
}
if s.Progressing > 0 {
return StateProgressing
}
if s.Pending > 0 {
return StatePending
}
if s.Unknown > 0 || s.GetTotalCount() != s.Total {
return StateUnknown
}
return StateSucceeded
}

func TruncateString(s string, max int) string {
if len(s) > max {
return s[:max]
}
return s
}

func Hash(num int64) string {
// generate the SHA-256 hash of the bytes
hash := sha256.Sum256([]byte(strconv.FormatInt(num, 10)))
// take the first 4 bytes of the hash and convert to hex
return hex.EncodeToString(hash[:4])
}

type CheckType string

const PreDeploymentCheckType CheckType = "pre"
const PostDeploymentCheckType CheckType = "post"
const PreDeploymentEvaluationCheckType CheckType = "pre-eval"
const PostDeploymentEvaluationCheckType CheckType = "post-eval"

type KeptnMeters struct {
TaskCount metric.Int64Counter
TaskDuration metric.Float64Histogram
DeploymentCount metric.Int64Counter
DeploymentDuration metric.Float64Histogram
AppCount metric.Int64Counter
AppDuration metric.Float64Histogram
EvaluationCount metric.Int64Counter
EvaluationDuration metric.Float64Histogram
}

const (
AppName attribute.Key = attribute.Key("keptn.deployment.app.name")
AppVersion attribute.Key = attribute.Key("keptn.deployment.app.version")
AppNamespace attribute.Key = attribute.Key("keptn.deployment.app.namespace")
AppStatus attribute.Key = attribute.Key("keptn.deployment.app.status")
AppPreviousVersion attribute.Key = attribute.Key("keptn.deployment.app.previousversion")
WorkloadName attribute.Key = attribute.Key("keptn.deployment.workload.name")
WorkloadVersion attribute.Key = attribute.Key("keptn.deployment.workload.version")
WorkloadPreviousVersion attribute.Key = attribute.Key("keptn.deployment.workload.previousversion")
WorkloadNamespace attribute.Key = attribute.Key("keptn.deployment.workload.namespace")
WorkloadStatus attribute.Key = attribute.Key("keptn.deployment.workload.status")
TaskStatus attribute.Key = attribute.Key("keptn.deployment.task.status")
TaskName attribute.Key = attribute.Key("keptn.deployment.task.name")
TaskType attribute.Key = attribute.Key("keptn.deployment.task.type")
EvaluationStatus attribute.Key = attribute.Key("keptn.deployment.evaluation.status")
EvaluationName attribute.Key = attribute.Key("keptn.deployment.evaluation.name")
EvaluationType attribute.Key = attribute.Key("keptn.deployment.evaluation.type")
)

func GenerateTaskName(checkType CheckType, taskName string) string {
randomId := rand.Intn(99_999-10_000) + 10000
return operatorcommon.CreateResourceName(MaxK8sObjectLength, MinKeptnNameLen, string(checkType), taskName, strconv.Itoa(randomId))
}

func GenerateJobName(taskName string) string {
randomId := rand.Intn(99_999-10_000) + 10000
return operatorcommon.CreateResourceName(MaxK8sObjectLength, MinKeptnNameLen, taskName, strconv.Itoa(randomId))
}

func GenerateEvaluationName(checkType CheckType, evalName string) string {
randomId := rand.Intn(99_999-10_000) + 10000
return operatorcommon.CreateResourceName(MaxK8sObjectLength, MinKeptnNameLen, string(checkType), evalName, strconv.Itoa(randomId))
}

// MergeMaps merges two maps into a new map. If a key exists in both maps, the
// value of the second map is picked.
func MergeMaps(m1 map[string]string, m2 map[string]string) map[string]string {
merged := make(map[string]string, len(m1)+len(m2))
for key, value := range m1 {
merged[key] = value
}
for key, value := range m2 {
merged[key] = value
}
return merged
}

// IsOwnerSupported returns whether the owner of the given object is supported to be considered a KeptnWorkload
func IsOwnerSupported(owner metav1.OwnerReference) bool {
return owner.Kind == "ReplicaSet" || owner.Kind == "Deployment" || owner.Kind == "StatefulSet" || owner.Kind == "DaemonSet" || owner.Kind == "Rollout"
}
Loading

0 comments on commit 11b7ea2

Please sign in to comment.