Skip to content

Commit

Permalink
feat(controller): add canary steps plugin (#3521)
Browse files Browse the repository at this point in the history
* making code for step plugin

Signed-off-by: Alexandre Gaudreault <[email protected]>

* codegen

Signed-off-by: Alexandre Gaudreault <[email protected]>

* unit tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* rpc tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* add rpc plugin tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* better message

Signed-off-by: Alexandre Gaudreault <[email protected]>

* add order test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* implement terminate

Signed-off-by: Alexandre Gaudreault <[email protected]>

* Terminate tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* aborted logic + some unit test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* unit test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* abort test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* load plugin

Signed-off-by: Alexandre Gaudreault <[email protected]>

* more tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* dont use newStatus

Signed-off-by: Alexandre Gaudreault <[email protected]>

* codegen preserve fields

Signed-off-by: Alexandre Gaudreault <[email protected]>

* some test before full promote problem

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix full promotion

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix plugins

Signed-off-by: Alexandre Gaudreault <[email protected]>

* codegen

Signed-off-by: Alexandre Gaudreault <[email protected]>

* add disabled rollout

Signed-off-by: Alexandre Gaudreault <[email protected]>

* codegen

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix duration cast

Signed-off-by: Alexandre Gaudreault <[email protected]>

* refactor to use context object

Signed-off-by: Alexandre Gaudreault <[email protected]>

* adding debug logs.

Signed-off-by: Alexandre Gaudreault <[email protected]>

* need to adjust the backoff on each reconcile

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix e2e

Signed-off-by: Alexandre Gaudreault <[email protected]>

* unit test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix abort and promote logic

Signed-off-by: Alexandre Gaudreault <[email protected]>

* fix aborted rollout do not retry

Signed-off-by: Alexandre Gaudreault <[email protected]>

* add event

Signed-off-by: Alexandre Gaudreault <[email protected]>

* change enabled to status

Signed-off-by: Alexandre Gaudreault <[email protected]>

* unit tests

Signed-off-by: Alexandre Gaudreault <[email protected]>

* more test

Signed-off-by: Alexandre Gaudreault <[email protected]>

* cleanup

Signed-off-by: Alexandre Gaudreault <[email protected]>

* add docs

Signed-off-by: Alexandre Gaudreault <[email protected]>

* docs

Signed-off-by: Alexandre Gaudreault <[email protected]>

* makefile for e2e

Signed-off-by: Alexandre Gaudreault <[email protected]>

* disable e2e when not configured

Signed-off-by: Alexandre Gaudreault <[email protected]>

* Add some UI for the extension

Signed-off-by: Alexandre Gaudreault <[email protected]>

* codegen

Signed-off-by: Zach Aller <[email protected]>

---------

Signed-off-by: Alexandre Gaudreault <[email protected]>
Signed-off-by: Zach Aller <[email protected]>
Co-authored-by: Zach Aller <[email protected]>
  • Loading branch information
agaudreault and zachaller authored Aug 8, 2024
1 parent 48131eb commit 74c1a94
Show file tree
Hide file tree
Showing 61 changed files with 7,233 additions and 786 deletions.
3 changes: 3 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ FROM gcr.io/distroless/static-debian11

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY rollouts-controller-linux-amd64 /bin/rollouts-controller
COPY step-plugin-e2e-linux-amd64 /bin/plugin-files/step-plugin-e2e

# Use numeric user, allows kubernetes to identify this user as being
# non-root when we use a security context with runAsNonRoot: true
USER 999

WORKDIR /home/argo-rollouts

ENTRYPOINT [ "/bin/rollouts-controller" ]
32 changes: 25 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ GIT_TREE_STATE=$(shell if [ -z "`git status --porcelain`" ]; then echo "clean" ;
GIT_REMOTE_REPO=upstream
VERSION=$(shell if [ ! -z "${GIT_TAG}" ] ; then echo "${GIT_TAG}" | sed -e "s/^v//" ; else cat VERSION ; fi)


TARGET_ARCH?=linux/amd64

# docker image publishing options
DOCKER_PUSH=false
IMAGE_TAG=latest
DOCKER_PUSH ?= false
IMAGE_TAG ?= latest
# build development images
DEV_IMAGE ?= false

# E2E variables
E2E_K8S_CONTEXT ?= rancher-desktop
E2E_INSTANCE_ID ?= argo-rollouts-e2e
E2E_TEST_OPTIONS ?=
E2E_PARALLEL ?= 1
Expand Down Expand Up @@ -149,6 +153,9 @@ gen-crd: install-go-tools-local ## generate crd manifests
gen-mocks: install-go-tools-local ## generate mock files
./hack/update-mocks.sh

gen-mocks-fast:
./hack/update-mocks.sh

# generates openapi_generated.go
.PHONY: gen-openapi
gen-openapi: $(DIST_DIR)/openapi-gen ## generate openapi files
Expand Down Expand Up @@ -200,10 +207,11 @@ builder-image: ## build builder image
.PHONY: image
image:
ifeq ($(DEV_IMAGE), true)
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/step-plugin-e2e-linux-amd64 ./test/cmd/step-plugin-e2e
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -ldflags '${LDFLAGS}' -o ${DIST_DIR}/rollouts-controller-linux-amd64 ./cmd/rollouts-controller
DOCKER_BUILDKIT=1 docker build -t $(IMAGE_PREFIX)argo-rollouts:$(IMAGE_TAG) -f Dockerfile.dev ${DIST_DIR}
DOCKER_BUILDKIT=1 docker build --platform=$(TARGET_ARCH) -t $(IMAGE_PREFIX)argo-rollouts:$(IMAGE_TAG) -f Dockerfile.dev ${DIST_DIR}
else
DOCKER_BUILDKIT=1 docker build -t $(IMAGE_PREFIX)argo-rollouts:$(IMAGE_TAG) .
DOCKER_BUILDKIT=1 docker build --platform=$(TARGET_ARCH) -t $(IMAGE_PREFIX)argo-rollouts:$(IMAGE_TAG) .
endif
@if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)argo-rollouts:$(IMAGE_TAG) ; fi

Expand All @@ -212,15 +220,19 @@ endif
# https://www.jetbrains.com/help/go/attach-to-running-go-processes-with-debugger.html
.PHONY: build-sample-metric-plugin-debug
build-sample-metric-plugin-debug: ## build sample metric plugin with debug info
go build -gcflags="all=-N -l" -o metric-plugin test/cmd/metrics-plugin-sample/main.go
go build -gcflags="all=-N -l" -o plugin-bin/metric-plugin test/cmd/metrics-plugin-sample/main.go

.PHONY: build-sample-traffic-plugin-debug
build-sample-traffic-plugin-debug: ## build sample traffic plugin with debug info
go build -gcflags="all=-N -l" -o traffic-plugin test/cmd/trafficrouter-plugin-sample/main.go
go build -gcflags="all=-N -l" -o plugin-bin/traffic-plugin test/cmd/trafficrouter-plugin-sample/main.go

.PHONY: build-sample-step-plugin-debug
build-sample-step-plugin-debug: ## build sample traffic plugin with debug info
go build -gcflags="all=-N -l" -o plugin-bin/step-plugin test/cmd/step-plugin-sample/main.go

.PHONY: plugin-image
plugin-image: ## build plugin image
DOCKER_BUILDKIT=1 docker build --target kubectl-argo-rollouts -t $(IMAGE_PREFIX)kubectl-argo-rollouts:$(IMAGE_TAG) .
DOCKER_BUILDKIT=1 docker build --platform=$(TARGET_ARCH) --target kubectl-argo-rollouts -t $(IMAGE_PREFIX)kubectl-argo-rollouts:$(IMAGE_TAG) .
if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)kubectl-argo-rollouts:$(IMAGE_TAG) ; fi

##@ Test
Expand All @@ -233,6 +245,12 @@ test: test-kustomize ## run all tests
test-kustomize: ## run kustomize tests
./test/kustomize/test.sh

setup-e2e:
@kubectl apply --context='${E2E_K8S_CONTEXT}' -f manifests/crds/rollout-crd.yaml
@kubectl apply --context='${E2E_K8S_CONTEXT}' -n argo-rollouts -f test/e2e/step-plugin/argo-rollouts-config.yaml
@rm -rf plugin-bin
@go build -gcflags="all=-N -l" -o plugin-bin/e2e-step-plugin test/cmd/step-plugin-e2e/main.go

.PHONY: start-e2e
start-e2e: ## start e2e test environment
mkdir -p coverage-output-e2e
Expand Down
80 changes: 43 additions & 37 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
# Contributing

## Before You Start

Argo Rollouts is written in Golang. If you do not have a good grounding in Go, try out [the tutorial](https://tour.golang.org/).

## Pre-requisites

Install:

* [docker](https://docs.docker.com/install/#supported-platforms)
* [golang](https://golang.org/)
* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)
* [kustomize](https://github.com/kubernetes-sigs/kustomize/releases) >= 4.5.5
* [k3d](https://k3d.io/) recommended
- [docker](https://docs.docker.com/install/#supported-platforms)
- [golang](https://golang.org/)
- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)
- [kustomize](https://github.com/kubernetes-sigs/kustomize/releases) >= 4.5.5
- [k3d](https://k3d.io/) recommended

Kustomize is required for unit tests (`make test` is using it), so you [must install it](https://kubectl.docs.kubernetes.io/installation/kustomize/)
locally if you wish to make code contributions to Argo Rollouts.

Argo Rollout additionally uses the following tools

* `golangci-lint` to lint the project.
* `protoc` and `swagger-codegen` to generate proto related files
* `yarn` to build the UI
- `golangci-lint` to lint the project.
- `protoc` and `swagger-codegen` to generate proto related files
- `yarn` to build the UI

Run the following commands to install them:

Expand Down Expand Up @@ -56,10 +59,9 @@ cd ~/go/src/github.com/argoproj/argo-rollouts

The `make controller` command will build the controller.

* `make install-tools-local` - Runs scripts to install codegen utility CLIs necessary for codegen.

* `make codegen` - Runs the code generator that creates the informers, client, lister, and deepcopies from the types.go and modifies the open-api spec.
- `make install-tools-local` - Runs scripts to install codegen utility CLIs necessary for codegen.

- `make codegen` - Runs the code generator that creates the informers, client, lister, and deepcopies from the types.go and modifies the open-api spec.

## Running Controller Locally

Expand All @@ -83,11 +85,7 @@ make test
## Running E2E tests

The end-to-end tests need to run against a kubernetes cluster with the Argo Rollouts controller
running. The rollout controller can be started with the command:

```
make start-e2e
```
running.

Start and prepare your cluster for e2e tests:

Expand All @@ -98,6 +96,12 @@ kubectl apply -k manifests/crds
kubectl apply -f test/e2e/crds
```

The rollout controller can be started with the command:

```
make start-e2e
```

Then run the e2e tests:

```
Expand All @@ -112,9 +116,10 @@ E2E_TEST_OPTIONS="-run 'TestCanarySuite' -testify.m 'TestCanaryScaleDownOnAbortN

## Running the UI

If you'd like to run the UI locally, you first need a running Rollouts controller. This can be a locally running controller with a k3d cluster, as described above, or a controller running in a remote Kubernetes cluster.
If you'd like to run the UI locally, you first need a running Rollouts controller. This can be a locally running controller with a k3d cluster, as described above, or a controller running in a remote Kubernetes cluster.

In order for the local React app to communicate with the controller and Kubernetes API, run the following to open a port forward to the dashboard:

```bash
kubectl argo rollouts dashboard
```
Expand All @@ -127,6 +132,7 @@ make plugin
```

In another terminal, run the following to start the UI:

```bash
cd ui
yarn install
Expand All @@ -142,11 +148,11 @@ that handle a specific aspect of Progressive Delivery.

The controllers are:

* [Rollout Controller](https://github.com/argoproj/argo-rollouts/blob/master/rollout/controller.go)
* [Service Controller](https://github.com/argoproj/argo-rollouts/blob/master/service/service.go)
* [Ingress Controller](https://github.com/argoproj/argo-rollouts/blob/master/ingress/ingress.go)
* [Experiment Controller](https://github.com/argoproj/argo-rollouts/blob/master/experiments/controller.go)
* [AnalysisRun Controller](https://github.com/argoproj/argo-rollouts/blob/master/analysis/controller.go)
- [Rollout Controller](https://github.com/argoproj/argo-rollouts/blob/master/rollout/controller.go)
- [Service Controller](https://github.com/argoproj/argo-rollouts/blob/master/service/service.go)
- [Ingress Controller](https://github.com/argoproj/argo-rollouts/blob/master/ingress/ingress.go)
- [Experiment Controller](https://github.com/argoproj/argo-rollouts/blob/master/experiments/controller.go)
- [AnalysisRun Controller](https://github.com/argoproj/argo-rollouts/blob/master/analysis/controller.go)

### Tips

Expand All @@ -158,36 +164,35 @@ KUBECONFIG=~/.kube/minikube make test-e2e
```

2. To run a specific e2e test, set the `E2E_TEST_OPTIONS` environment variable to specify the test
(or test regex):
(or test regex):

```shell
make test-e2e E2E_TEST_OPTIONS="-testify.m ^TestRolloutRestart$"
```

3. The e2e tests are designed to run as quickly as possible, eliminating readiness and termination
delays. However, it is often desired to artificially slow down the tests for debugging purposes,
as well as to understand what the test is doing. To delay startup and termination of pods, set the
`E2E_POD_DELAY` to an integer value in seconds. This environment variable is often coupled with
`E2E_TEST_OPTIONS` to debug and slow down a specific test.
delays. However, it is often desired to artificially slow down the tests for debugging purposes,
as well as to understand what the test is doing. To delay startup and termination of pods, set the
`E2E_POD_DELAY` to an integer value in seconds. This environment variable is often coupled with
`E2E_TEST_OPTIONS` to debug and slow down a specific test.

```shell
make test-e2e E2E_POD_DELAY=10
```

4. Increasing the timeout. The E2E tests time out waiting on conditions to be met within 60 seconds.
If debugging the rollout controller, it may be useful to increase this timeout while say sitting
at a debugger breakpoint:
If debugging the rollout controller, it may be useful to increase this timeout while say sitting
at a debugger breakpoint:

```shell
make test-e2e E2E_WAIT_TIMEOUT=999999
```


5. The e2e tests leverage a feature of the controller allowing the controller to be sharded with
a user-specific "instance id" label. This allows the tests to operate only on rollouts with the
specified label, and prevents any other controllers (including the system rollout controller),
from also operating on the same set of rollouts. This value can be changed (from the default of
`argo-rollouts-e2e`), using the `E2E_INSTANCE_ID` environment variable:
a user-specific "instance id" label. This allows the tests to operate only on rollouts with the
specified label, and prevents any other controllers (including the system rollout controller),
from also operating on the same set of rollouts. This value can be changed (from the default of
`argo-rollouts-e2e`), using the `E2E_INSTANCE_ID` environment variable:

```shell
make start-e2e E2E_INSTANCE_ID=foo
Expand All @@ -200,7 +205,6 @@ Alternatively, the e2e tests can be run against the system controller (i.e. with
make start-e2e E2E_INSTANCE_ID=''
```


6. Working on CRDs? While editing them directly works when you are finding the shape of things you want, the final CRDs are autogenerated. Make sure to regenerate them by running `make gen-crd` before submitting PRs. They are controlled by the relevant annotations in the types file:

eg: Analysis Templates are controlled by annotations in `pkg/apis/rollouts/v1alpha1/analysis_types.go`.
Expand Down Expand Up @@ -242,14 +246,16 @@ kubectl -n argo-rollouts apply -f manifests/install.yaml
```

## Upgrading Kubernetes Libraries

Argo Rollouts has a dependency on the kubernetes/kubernetes repo for some of the functionality that has not been
pushed into the other kubernetes repositories yet. In order to import the kubernetes/kubernetes repo, all of the
associated repos have to pinned to the correct version specified by the kubernetes/kubernetes release. The
`./hack/update-k8s-dependencies.sh` updates all the dependencies to the those correct versions.

## Upgrading Notifications Engine
Argo Rollouts has a dependency on the [argoproj/notifications-engines](https://github.com/argoproj/notifications-engine) repo
for the notifications functionality and related documentation.

Argo Rollouts has a dependency on the [argoproj/notifications-engines](https://github.com/argoproj/notifications-engine) repo
for the notifications functionality and related documentation.

This is updated by upgrading the Go library in `go.mod` by running the commands:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/gogo/protobuf v1.3.2
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.4
github.com/google/uuid v1.6.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/hashicorp/go-plugin v1.6.1
github.com/influxdata/influxdb-client-go/v2 v2.13.0
Expand Down Expand Up @@ -128,7 +129,6 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions hack/update-mocks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ mockery \
--dir "${PROJECT_ROOT}"/rollout/trafficrouting \
--name TrafficRoutingReconciler \
--output "${PROJECT_ROOT}"/rollout/mocks

mockery \
--dir "${PROJECT_ROOT}"/rollout/steps/plugin \
--name "Resolver|StepPlugin" \
--output "${PROJECT_ROOT}"/rollout/steps/plugin/mocks

mockery \
--dir "${PROJECT_ROOT}"/rollout/steps/plugin/rpc \
--name "StepPlugin" \
--output "${PROJECT_ROOT}"/rollout/steps/plugin/rpc/mocks
49 changes: 49 additions & 0 deletions manifests/crds/rollout-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,16 @@ spec:
- type: string
x-kubernetes-int-or-string: true
type: object
plugin:
properties:
config:
type: object
x-kubernetes-preserve-unknown-fields: true
name:
type: string
required:
- name
type: object
setCanaryScale:
properties:
matchTrafficWeight:
Expand Down Expand Up @@ -3721,6 +3731,45 @@ spec:
type: object
stablePingPong:
type: string
stepPluginStatuses:
items:
properties:
backoff:
type: string
disabled:
type: boolean
executions:
format: int32
type: integer
finishedAt:
format: date-time
type: string
index:
format: int32
type: integer
message:
type: string
name:
type: string
operation:
type: string
phase:
type: string
startedAt:
format: date-time
type: string
status:
type: object
x-kubernetes-preserve-unknown-fields: true
updatedAt:
format: date-time
type: string
required:
- index
- name
- operation
type: object
type: array
weights:
properties:
additional:
Expand Down
Loading

0 comments on commit 74c1a94

Please sign in to comment.