Skip to content

Commit

Permalink
Merge pull request #8 from prosimcorp/feat/add-argo-rollout-support
Browse files Browse the repository at this point in the history
Feat/add argo rollout support
  • Loading branch information
achetronic authored Aug 13, 2024
2 parents cf6eec4 + dd3c826 commit 051cf35
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 10 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ restart the related workload.
This is exactly what this operator does, but with vitamins:
* Includes [GJSON](https://github.com/tidwall/gjson) on conditions to look for a particular field in the huge JSON given by RabbitMQ
* It supports giving credentials (or not) to access RabbitMQ
* Support restarting several workload types: `Deployment` `DaemonSet` `StatefulSet`
* Support restarting several workload types: `Deployment` `DaemonSet` `StatefulSet` `Argo Rollout`

Any discussion can be done on issues. Most interesting questions will be included on our [FAQ section](./README.md#faq-frequently-asked-questions)

Expand Down Expand Up @@ -109,10 +109,17 @@ spec:

# The workload affected by the action
workloadRef:
# It's possible to use core resources from Kubernetes
apiVersion: apps/v1
kind: Deployment
name: testing-workload
namespace: default

# Some custom resources can be used too
# apiVersion: argoproj.io/v1alpha1
# kind: Rollout
# name: testing-workload-argo-rollout
# namespace: default
```

#### Queue names/regex
Expand Down
16 changes: 16 additions & 0 deletions config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
# Non core supported CRDs to test
- https://raw.githubusercontent.com/argoproj/argo-rollouts/master/manifests/crds/rollout-crd.yaml

# Core workloads
- testing-secret.yaml
- testing-workload.yaml

# Non core workloads
- testing-workload-argo-rollout.yaml

#
- rabbit-stalker_v1alpha1_workloadaction.yaml
16 changes: 12 additions & 4 deletions config/samples/rabbit-stalker_v1alpha1_workloadaction.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
rabbitConnection:
url: "https://your-server.rmq.cloudamqp.com"
queue: "your-queue-here"
useRegex: true
useRegex: false

# (Optional) Vhost can be set (or not) when searching queues using regex patterns,
# (Mandatory) Vhost is required for searches based on exact queue names.
Expand Down Expand Up @@ -63,8 +63,16 @@ spec:

# The workload affected by the action
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: testing-workload

# It's possible to use core resources from Kubernetes
#apiVersion: apps/v1
#kind: Deployment
#name: testing-workload
#namespace: default

# Some custom resources can be used too
apiVersion: argoproj.io/v1alpha1
kind: Rollout
name: testing-workload-argo-rollout
namespace: default

17 changes: 17 additions & 0 deletions config/samples/testing-workload-argo-rollout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: testing-workload-argo-rollout

# .spec.restartAt is the field that must change for a Rollout
spec:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: testing-workload
# scaleDown: never|onsuccess|progressively
scaleDown: never




24 changes: 19 additions & 5 deletions controllers/workloadaction_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const (
ResourceKindDeployment = "Deployment"
ResourceKindStatefulSet = "StatefulSet"
ResourceKindDaemonSet = "DaemonSet"
ResourceKindArgoRollout = "Rollout"

// TODO
ActionDelete = "delete"
Expand Down Expand Up @@ -320,7 +321,7 @@ func defaultPatchConstructor(obj *unstructured.Unstructured) (patch PatchConstru
return patch, err
}

// deploymentPatchConstructor return a patch for deployment resources to be used in SetWorkloadRestartAnnotation
// deploymentPatchConstructor return a patch for deployment resources to be used in SetWorkloadRestartPatch
func deploymentPatchConstructor(obj *unstructured.Unstructured) (patch PatchConstructorPatchT, err error) {
pausedValue, found, err := unstructured.NestedBool(obj.Object, "spec", "paused")
if err != nil {
Expand All @@ -337,14 +338,27 @@ func deploymentPatchConstructor(obj *unstructured.Unstructured) (patch PatchCons
return patch, err
}

// SetWorkloadRestartAnnotation restart a workload by changing an annotation.
// This will trigger an automatic reconciliation on the workload in the same way done by kubectl
func (r *WorkloadActionReconciler) SetWorkloadRestartAnnotation(ctx context.Context, obj *unstructured.Unstructured) (err error) {
// argoRolloutPatchConstructor return a patch for Argo Rollout resources to be used in SetWorkloadRestartPatch
// Ref: https://argo-rollouts.readthedocs.io/en/stable/features/restart/
func argoRolloutPatchConstructor(obj *unstructured.Unstructured) (patch PatchConstructorPatchT, err error) {

patchTimestamp := time.Now().Format(time.RFC3339)

patch.Patch = []byte(fmt.Sprintf(`{"spec":{"restartAt":"%s"}}`, patchTimestamp))
patch.PatchType = types.MergePatchType

return patch, nil
}

// SetWorkloadRestartPatch restart a workload by changing a field into the specified object.
// This will trigger an automatic reconciliation on the workload in the same way done by kubectl, ArgoRollouts, etc.
func (r *WorkloadActionReconciler) SetWorkloadRestartPatch(ctx context.Context, obj *unstructured.Unstructured) (err error) {

var patchConstructorMap map[string]PatchConstructorFuncPointerT = map[string]PatchConstructorFuncPointerT{
ResourceKindDeployment: deploymentPatchConstructor,
ResourceKindStatefulSet: defaultPatchConstructor,
ResourceKindDaemonSet: defaultPatchConstructor,
ResourceKindArgoRollout: argoRolloutPatchConstructor,
}

resourceType := obj.GetObjectKind().GroupVersionKind()
Expand Down Expand Up @@ -663,7 +677,7 @@ func (r *WorkloadActionReconciler) reconcileWorkloadAction(ctx context.Context,
// 7. Condition is met. Execute the action
switch workloadActionManifest.Spec.Action {
case ActionRestart:
err = r.SetWorkloadRestartAnnotation(ctx, targetObject)
err = r.SetWorkloadRestartPatch(ctx, targetObject)
case ActionDelete:
err = errors.New(DeleteActionNotImplementedErrorMessage)
default:
Expand Down

0 comments on commit 051cf35

Please sign in to comment.