diff --git a/Makefile b/Makefile index 438d9790f..13981350f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SHELL ?= /bin/bash ARGO_CD_CHART_VERSION := 5.51.6 -ARGO_ROLLOUTS_CHART_VERSION := 2.32.8 +ARGO_ROLLOUTS_CHART_VERSION := 2.33.0 BUF_LINT_ERROR_FORMAT ?= text GO_LINT_ERROR_FORMAT ?= colored-line-number CERT_MANAGER_CHART_VERSION := 1.11.5 @@ -258,12 +258,12 @@ hack-install-argocd: .PHONY: hack-install-argo-rollouts hack-install-argo-rollouts: - helm upgrade rollouts argo-rollouts \ + helm upgrade argo-rollouts argo-rollouts \ --repo https://argoproj.github.io/argo-helm \ --version $(ARGO_ROLLOUTS_CHART_VERSION) \ --install \ --create-namespace \ - --namespace rollouts \ + --namespace argo-rollouts \ --wait .PHONY: hack-uninstall-prereqs @@ -271,7 +271,7 @@ hack-uninstall-prereqs: hack-uninstall-argo-rollouts hack-uninstall-argocd hack- .PHONY: hack-uninstall-argo-rollouts hack-uninstall-argo-rollouts: - helm delete rollouts --namespace rollouts + helm delete argo-rollouts --namespace argo-rollouts .PHONY: hack-uninstall-argocd hack-uninstall-argocd: diff --git a/docs/docs/15-concepts.md b/docs/docs/15-concepts.md index 6d8b40805..37d624e96 100644 --- a/docs/docs/15-concepts.md +++ b/docs/docs/15-concepts.md @@ -207,10 +207,110 @@ spec: appNamespace: argocd ``` +#### Verifications + +The `spec.verification` field is used to describe optional verification +processes that should be executed after a `Promotion` has successfully deployed +`Freight` to a `Stage`, and if applicable, after the `Stage` has reached a +healthy state. + +Verification processes are defined through _references_ to one or more +[Argo Rollouts `AnalysisTemplate` resources](https://argoproj.github.io/argo-rollouts/features/analysis/) +that reside in the same project/namespace as the `Stage` resource. + +:::info +Argo Rollouts `AnalysisTemplate` resources (and the `AnalysisRun` resources that +are spawned from them) were intentionally built to be re-usable in contexts +other than Argo Rollouts. Re-using this resource type to define verification +processes means those processes benefit from this rich and battle-tested feature +of Argo Rollouts. +::: + +The following example depicts a `Stage` resource that references an +`AnalysisTemplate` named `kargo-demo` to validate the `test` `Stage` after any +successful `Promotion`: + +```yaml +apiVersion: kargo.akuity.io/v1alpha1 +kind: Stage +metadata: + name: test + namespace: kargo-demo +spec: + # ... + verification: + analysisTemplates: + - name: kargo-demo +``` + +It is also possible to specify additional labels, annotations, and arguments +that should be applied to `AnalysisRun` resources spawned from the referenced +`AnalysisTemplate`: + +```yaml +apiVersion: kargo.akuity.io/v1alpha1 +kind: Stage +metadata: + name: test + namespace: kargo-demo +spec: + # ... + verification: + analysisTemplates: + - name: kargo-demo + analysisRunMetadata: + labels: + foo: bar + annotations: + bat: baz + args: + - name: foo + value: bar +``` + +An `AnalysisTemplate` could be as simple as the following, which merely executes +a Kubernetes `Job` that is defined inline: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: AnalysisTemplate +metadata: + name: kargo-demo + namespace: kargo-demo +spec: + metrics: + - name: test + provider: + job: + metadata: + spec: + backoffLimit: 1 + template: + spec: + containers: + - name: test + image: alpine:latest + command: + - sleep + - "10" + restartPolicy: Never +``` + +:::note +Please consult the +[relevant sections](https://argoproj.github.io/argo-rollouts/features/analysis/) +of the Argo Rollouts documentation for comprehensive coverage of the full range +of `AnalysisTemplate` capabilities. +::: + #### Status A `Stage` resource's `status` field records: +* The current phase of the `Stage` resource's lifecycle. + +* Information about any in-progress `Promotion`. + * The `Freight` currently deployed to the `Stage`. * History of `Freight` that has been deployed to the `Stage`. (From most to @@ -218,10 +318,13 @@ A `Stage` resource's `status` field records: * The health status any any associated Argo CD `Application` resources. +* The status of any in-progress of completed verification processes. + For example: ```yaml status: + phase: Steady currentFreight: id: 47b33c0c92b54439e5eb7fb80ecc83f8626fe390 images: @@ -230,6 +333,11 @@ status: commits: - repoURL: https://github.com/example/kargo-demo.git id: 1234abc + verificationResult: + analysisRun: + namespace: kargo-demo + name: test.ab85b188-0ad5-43d9-a36d-ddcf63666183.47b33c0 + phase: Successful health: argoCDApps: - healthStatus: @@ -248,6 +356,11 @@ status: commits: - repoURL: https://github.com/example/kargo-demo.git id: 1234abc + verificationResult: + analysisRun: + namespace: kargo-demo + name: test.ab85b188-0ad5-43d9-a36d-ddcf63666183.47b33c0 + phase: Successful ``` ### `Freight` Resources diff --git a/docs/docs/20-quickstart.mdx b/docs/docs/20-quickstart.mdx index 41dbeb488..1e1cee948 100644 --- a/docs/docs/20-quickstart.mdx +++ b/docs/docs/20-quickstart.mdx @@ -124,6 +124,7 @@ Any approach you select should only: 1. Launch a new, local Kubernetes cluster, if applicable 1. Install cert-manager 1. Install Argo CD +1. Install Argo Rollouts 1. Install Kargo ::: @@ -437,10 +438,10 @@ the previous section. Sample output: ```shell - NAME CURRENT FREIGHT HEALTH AGE - prod Healthy 20s - test Healthy 20s - uat Healthy 20s + NAME CURRENT FREIGHT HEALTH PHASE AGE + prod NotApplicable 20s + test NotApplicable 20s + uat NotApplicable 20s ``` 1. Our `Warehouse`, which subscribes to the `nginx` image repository, also @@ -453,8 +454,8 @@ the previous section. Sample output: ```shell - NAME AGE - 47b33c0c92b54439e5eb7fb80ecc83f8626fe390 5m49s + NAME/ID ALIAS AGE + f5f87aa23c9e97f43eb83dd63768ee41f5ba3766 mortal-dragonfly 35s ``` :::info `Freight` is a set of references to one or more versioned artifacts, which @@ -480,13 +481,13 @@ the previous section. 1. Now, let's _promote_ the `Freight` into the `test` `Stage`: ```shell - kargo stage promote kargo-demo test --freight $FREIGHT_ID + kargo stage promote --project kargo-demo test --freight $FREIGHT_ID ``` Sample output: ```shell - Promotion Created: "test.01haswttm2p4qwcenpnn5s1m96.b73f9d1" + Promotion Created: "test.01hj7grh2m556rqxq72ame6a3z.f5f87aa" ``` Query for `Promotion` resources within our project to see one has been @@ -501,7 +502,7 @@ the previous section. ```shell NAME STAGE FREIGHT PHASE AGE - test.01haswttm2p4qwcenpnn5s1m96.b73f9d1 test b73f9d1afaca87254b64e64e5439557e86dcba79 Running 7s + test.01hj7grh2m556rqxq72ame6a3z.f5f87aa test f5f87aa23c9e97f43eb83dd63768ee41f5ba3766 Running 7s ``` Once the `Promotion` has succeeded, we can again view all `Stage` resources @@ -515,13 +516,13 @@ the previous section. Sample output: ```shell - NAME CURRENT FREIGHT HEALTH AGE - prod Healthy 6m55s - test b73f9d1afaca87254b64e64e5439557e86dcba79 Progressing 6m55s - uat Healthy 6m55s + NAME CURRENT FREIGHT HEALTH PHASE AGE + prod NotApplicable 118s + test f5f87aa23c9e97f43eb83dd63768ee41f5ba3766 Healthy Steady 119s + uat NotApplicable 118s ``` - We can repeat the command above until our `Promotion` is in a `Healthy` + We can repeat the command above until our `test` `Stage` is in a `Healthy` state and we can further validate the success of this entire process by visiting the test instance of our site at [localhost:30081](http://localhost:30081). @@ -540,9 +541,10 @@ the previous section. ```shell { "currentFreight": { - "id": "b73f9d1afaca87254b64e64e5439557e86dcba79", + "id": "f5f87aa23c9e97f43eb83dd63768ee41f5ba3766", "images": [ { + "digest": "sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026", "repoURL": "nginx", "tag": "1.25.3" } @@ -551,9 +553,10 @@ the previous section. ... "history": [ { - "id": "b73f9d1afaca87254b64e64e5439557e86dcba79", + "id": "f5f87aa23c9e97f43eb83dd63768ee41f5ba3766", "images": [ { + "digest": "sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026", "repoURL": "nginx", "tag": "1.25.3" } @@ -565,9 +568,16 @@ the previous section. 1. If we look at our `Freight` in greater detail, we'll see that by virtue of the `test` `Stage` having achieved a `Healthy` state, the `Freight` is now - _qualified_ in `test`, which designates it as eligible for promotion to the + _verified_ in `test`, which designates it as eligible for promotion to the next `Stage` -- in our case, `uat`. + :::note + Although this example does not demonstrate it, it is also possible to verify + the `Freight` in a `Stage` using user-defined processes. See the + [relevant section](./15-concepts.md#verifications) of the concepts page to + learn more. + ::: + ```shell kargo get freight $FREIGHT_ID --project kargo-demo --output jsonpath-as-json={.status} ``` @@ -576,7 +586,7 @@ the previous section. ```shell { - "qualifications": { + "verifiedIn": { "test": {} } } diff --git a/docs/docs/30-how-to-guides/10-installing-kargo.md b/docs/docs/30-how-to-guides/10-installing-kargo.md index ba2698836..2e84cc5d4 100644 --- a/docs/docs/30-how-to-guides/10-installing-kargo.md +++ b/docs/docs/30-how-to-guides/10-installing-kargo.md @@ -11,13 +11,15 @@ Installing Kargo with default configuration is quick and easy. You will need: -* [Helm](https://helm.sh/docs/): These instructions were tested with v3.11.2. -* A Kubernetes cluster with [cert-manager](https://cert-manager.io/) and - [Argo CD](https://argo-cd.readthedocs.io) pre-installed. These instructions - were tested with: - * Kubernetes: v1.25.3 +* [Helm](https://helm.sh/docs/): These instructions were tested with v3.13.1. +* A Kubernetes cluster with [cert-manager](https://cert-manager.io/), + [Argo CD](https://argo-cd.readthedocs.io), and + [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) + pre-installed. These instructions were tested with: + * Kubernetes: v1.27.4 * cert-manager: v1.11.5 - * Argo CD: v2.8.3 + * Argo CD: v2.9.3 + * Argo Rollouts: v1.6.4 :::info `cert-manager` is used for self-signing a certificate used to identify Kargo's @@ -27,8 +29,8 @@ other means. Refer to the advanced installation section for more information. ::: :::info -We are working toward transitioning Argo CD from a required dependency to a -_suggested_ dependency. +We are working toward transitioning Argo CD and Argo Rollouts from required +dependencies to _suggested_ dependencies. ::: :::note diff --git a/docs/docs/30-how-to-guides/20-managing-credentials.md b/docs/docs/30-how-to-guides/20-managing-credentials.md index eeb4549b0..5893b1d82 100644 --- a/docs/docs/30-how-to-guides/20-managing-credentials.md +++ b/docs/docs/30-how-to-guides/20-managing-credentials.md @@ -33,12 +33,15 @@ stringData: ``` The `name` of such a secret is inconsequential and may follow any convention -preferred by the user. The `namespace` of such a secret MUST match the namespace -of the Kargo `Stage` resources that will use it. +preferred by the user. :::info Kargo uses Kubernetes namespaces to demarcate project boundaries, so related `Stage` resources always share a namespace. + +Secrets representing credentials will typically exist in the same namespace as +the `Stage` resources that will require them. There are exceptions to this rule, +which are covered in the next section. ::: The label key `kargo.akuity.io/secret-type` and its value, one of `repository` @@ -69,6 +72,23 @@ Only username/password (or personal access token) authentication is fully-supported at this time. ::: +## Global Credentials + +In cases where one or more sets of credentials are needed widely across _all_ +Kargo projects, the administrator/operator installing Kargo may opt-in to +designating one or more namespaces as homes for "global" credentials using +the `controller.globalCredentials.enabled` and +`controller.globalCredentials.namespaces` settings in Kargo's Helm chart. +Refer to +[the advanced section of the installation guide](./10-installing-kargo.md#advanced-installation) +for more details. + +:::caution +It is important to understand the security implications of this feature. Any +credentials stored in a global credentials namespace will be available to _all_ +Kargo projects. +::: + ## Borrowing Credentials from Argo CD In many cases, Kargo and Argo CD will _both_ require credentials for the same diff --git a/docs/docs/30-how-to-guides/30-managing-user-permissions.md b/docs/docs/30-how-to-guides/30-managing-user-permissions.md new file mode 100644 index 000000000..ad43c9be3 --- /dev/null +++ b/docs/docs/30-how-to-guides/30-managing-user-permissions.md @@ -0,0 +1,112 @@ +--- +description: Learn how to manage user permissions +sidebar_label: Managing user permissions +--- + +# Managing User Permissions + +Kargo is typically configured to support single-sign-on (SSO) using an external +identity provider that implements the +[OpenID Connect](https://openid.net/developers/how-connect-works/) protocol. + +:::info +Refer to +[the advanced section of the installation guide](./10-installing-kargo.md#advanced-installation) +for more details on how to configure Kargo to use an external identity provider. +::: + +Kargo also implements authorization of all user actions using pure Kubernetes +[RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/). i.e. +Permission to perform various actions on various Kargo resources is therefore +granted via `RoleBinding` resources that associate users or `ServiceAccount` +resources with `Role` resources. + +Because Kargo users log into the Kargo CLI or UI via SSO, their identifies are +not known to Kargo's underlying Kubernetes cluster. This represents an +impediment to using Kubernetes RBAC to authorize the actions of such users. + +Kargo answers this challenge through a scheme that permits users to be mapped +to zero or more Kubernetes `ServiceAccount` resources. The remainder of this +page describes how to create those mappings. + +## User to `ServiceAccount` Mappings + +Whether logged into the Kargo CLI or UI, Kargo users are interacting with Kargo +via the Kargo API server. The Kargo API server authenticates users via a bearer +token issued by the external identity provider. On every request, the Kargo +API server validates and decodes the token to obtain trusted information about +the user. This includes: + +* The user's unique identifier (the standard OpenID Connect `sub` claim) +* The user's email address (the standard OpenID Connect `email` claim) +* Groups to which the user belongs (the non-standard, but widely supported + `groups` claim) + +Also at the time of authentication, the Kargo API server queries the Kubernetes +API server to obtain a list of all `ServiceAccount` resources to which the user +has been mapped. Kargo typically restricts this search to `ServiceAccount` resources +in Kargo project namespaces only (i.e. only those labeled with +`kargo.akuity.io/project: "true"`). Refer to the next section for exceptions to +this rule. + +ServiceAccount resources may be mapped to users through the use of three +different annotations: + +* `rbac.kargo.akuity.io/sub`: This annotation's value may be a comma-delimited + list of user identifiers. All users in the list will be mapped to the + `ServiceAccount`. + +* `rbac.kargo.akuity.io/email`: This annotation's value may be a comma-delimited + list of user email addresses. All users in the list having one of the listed + email addresses will be mapped to the `ServiceAccount`. + +* `rbac.kargo.akuity.io/groups`: This annotation's value may be a + comma-delimited list of group identifiers. All users in the list belonging to + one or more of the listed groups will be mapped to the `ServiceAccount`. + +In the following example, the `ServiceAccount` resource is mapped to all of: + +* A user identified as `bob`. +* A user with the email address `alice@example.com`. +* All users in the group `devops`. + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: admin + namespace: kargo-demo + annotations: + rbac.kargo.akuity.io/sub: bob + rbac.kargo.akuity.io/email: alice@example.com + rbac.kargo.akuity.io/groups: devops +``` + +:::note +Kargo has no built-in functionality for managing these `ServiceAccount` +resources and their annotations at this time, meaning they must currently be +managed through other means, such as `kubectl` or Argo CD. +::: + +A user may be mapped to multiple `ServiceAccount` resources. A user's effective +permissions are therefore the union of the permissions associated with all such +`ServiceAccount` resources. + +## Global Mappings + +In cases where certain, broad sets of permissions may be required by a large +numbers of users, the administrator/operator installing Kargo may opt-in to +designating one or more namespaces as homes for "global" `ServiceAccount` +resources using the `api.oidc.globalServiceAccounts` setting in Kargo's Helm +chart. Refer to +[the advanced section of the installation guide](./10-installing-kargo.md#advanced-installation) +for more details. + +Note that `ServiceAccount` resources in designated namespaces are not _truly_ +global because they are _still_ mapped to users according to the rules described +in the previous section. + +Making use of this feature could be, for instance, a convenient method of +granting read-only access to all Kargo resources in all projects to all users +within an organization. Additional permissions may then be granted to users on a +project-by-project basis. diff --git a/docs/docs/50-roadmap.md b/docs/docs/50-roadmap.md index 7a75f2d72..fcfcdeb9f 100644 --- a/docs/docs/50-roadmap.md +++ b/docs/docs/50-roadmap.md @@ -13,29 +13,37 @@ This roadmap is subject to change at any time, for the most up to date informati ## v0.2.0 +__Status:__ Completed + | Name | Type | Description | | ---- | ---- | ----------- | -| Freight and Warehouse CRDs | feature | Freight will change from being a property of a `Stage`, to being its own CRD. The source of where promotable `Freight` comes from will be known as a `Warehouse`. | -| GitHub PR-Based Promotion | feature | Support for pull request based promotions, which do not complete until the underlying PR is closed. | -| Kargo Render | breaking change | Bookkeeper to be rebranded as Kargo Render -- a Kargo child project for rendering manifests. | - +| `Freight` CRD | feature | Freight changed from being a property of a `Stage`, to being its own `Freight` CRD. | +| `Warehouse` CRD | feature | `Freight` production was decoupled from a pipeline's first `Stage` and now comes from a `Warehouse`. | +| Kargo Render | breaking change | The Bookkeeper project was rebranded as Kargo Render -- a Kargo sub-project for rendering manifests. | ## v0.3.0 +__Status:__ Completed + | Name | Type | Description | | ---- | ---- | ----------- | -| Analysis | feature | Ability to execute user-defined analysis steps to qualify or disqualify Freight for further promotion. | -| Improved RBAC | feature | Map SSO user identities to Kubernetes ServiceAccounts. Predefined ServiceAccount/Role/RoleBinding per project based on persona. | -| Freight Production Rules/Filters | feature | Git repository subscriptions options to constrain conditions under which new Freight is produced. | +| GitHub PR-Based Promotion | feature | Pull request-based promotions are now supported on GitHub. | +| Verifications | feature | `Stage` resources can now execute a user-defined verification process after a promotion. These can be defined using Argo Rollouts `AnalysisTemplate` resources, and executions take the form of `AnalysisRun` resources. | +| Improved RBAC | feature | SSO user identities can now be mapped to Kubernetes `ServiceAccount` resources using annotations. | ## v0.4.0 +__Status:__ In Progress + | Name | Type | Description | | ---- | ---- | ----------- | -| Project Management | feature | Introduce Project CRD to simplify onboarding and project lifecycle management. Support aggregate information at the project status level. Additional `PromotionPolicy` options. Credential management via CLI and UI. | +| `Warehouse` Rules/Filters | feature | Introduce features to constrain the conditions under which new `Freight` is produced. | +| Project Management | feature | | ## v0.5.0 +__Status:__ + | Name | Type | Description | | ---- | ---- | ----------- | | Promotion Mechanism Extensibility | feature | User-defined promotion mechanisms. | @@ -45,7 +53,7 @@ This roadmap is subject to change at any time, for the most up to date informati | Name | Type | Description | | ---- | ---- | ----------- | | Freight Enrichment | feature | Enhance Freight metadata for improved insight into Freight contents and the expected result of promoting a piece of Freight to a given environment. This data will be exposed to the UI and CLI tools. | -| `Improved Microservice Support | feature | Filters for Freightlines (for example, filter by Warehouse). Add the ability to merge parallel Freightlines at a control flow Stages. | +| Improved Microservice Support | feature | Filters for Freightlines (for example, filter by Warehouse). Add the ability to merge parallel Freightlines at a control flow Stages. | | `kargo init` | feature | Addition of an `init` sub-command to the Kargo CLI for streamlining project / pipeline creation. | | Standalone Image Writeback` | feature | Write back image changes without having to subscribe to an image repository. | | PromotionPolicy Improvements | feature | Add the ability to "freeze" Stages to prevent promotions. | diff --git a/hack/quickstart/install.sh b/hack/quickstart/install.sh index a2fe68b7b..001304d46 100755 --- a/hack/quickstart/install.sh +++ b/hack/quickstart/install.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -x + helm install cert-manager cert-manager \ --repo https://charts.jetstack.io \ --version 1.11.5 \ @@ -18,6 +20,16 @@ helm install argocd argo-cd \ --set notifications.enabled=false \ --set server.service.type=NodePort \ --set server.service.nodePortHttp=31443 \ + --set server.extensions.enabled=true \ + --set 'server.extensions.contents[0].name=argo-rollouts' \ + --set 'server.extensions.contents[0].url=https://github.com/argoproj-labs/rollout-extension/releases/download/v0.3.3/extension.tar' \ + --wait + +helm install argo-rollouts argo-rollouts \ + --repo https://argoproj.github.io/argo-helm \ + --version 2.33.0 \ + --create-namespace \ + --namespace argo-rollouts \ --wait helm install kargo \ diff --git a/hack/quickstart/k3d.sh b/hack/quickstart/k3d.sh index 0d12a58c2..1eece2a83 100755 --- a/hack/quickstart/k3d.sh +++ b/hack/quickstart/k3d.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -x + k3d cluster create kargo-quickstart \ --no-lb \ --k3s-arg '--disable=traefik@server:0' \ @@ -25,6 +27,16 @@ helm install argocd argo-cd \ --set notifications.enabled=false \ --set server.service.type=NodePort \ --set server.service.nodePortHttp=31443 \ + --set server.extensions.enabled=true \ + --set 'server.extensions.contents[0].name=argo-rollouts' \ + --set 'server.extensions.contents[0].url=https://github.com/argoproj-labs/rollout-extension/releases/download/v0.3.3/extension.tar' \ + --wait + +helm install argo-rollouts argo-rollouts \ + --repo https://argoproj.github.io/argo-helm \ + --version 2.33.0 \ + --create-namespace \ + --namespace argo-rollouts \ --wait helm install kargo \ diff --git a/hack/quickstart/kind.sh b/hack/quickstart/kind.sh index 642012cba..089eea7b4 100755 --- a/hack/quickstart/kind.sh +++ b/hack/quickstart/kind.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -x + kind create cluster \ --wait 120s \ --config - <