From 7c786943c55234e5b018b57ee56f92bd313dc40d Mon Sep 17 00:00:00 2001 From: Danil Grigorev Date: Wed, 27 Nov 2024 23:49:18 +0100 Subject: [PATCH] Release 0.4 prep (#119) * Multi stage and multi arch builds Signed-off-by: Danil-Grigorev * Add image name Signed-off-by: Danil-Grigorev * Update metadata for release v0.4.0 Signed-off-by: Danil-Grigorev * Fix clippy warnings Signed-off-by: Danil-Grigorev --------- Signed-off-by: Danil-Grigorev Co-authored-by: Dominic Giebert --- .dockerignore | 2 + .github/workflows/release.yaml | 17 +- Dockerfile | 11 +- metadata.yaml | 3 + src/api/fleet_bundle_deployment.rs | 693 +++++++++++++++++++++++++++++ src/api/fleet_cluster.rs | 6 +- src/api/fleet_clustergroup.rs | 6 +- src/controllers/cluster.rs | 1 + src/controllers/cluster_class.rs | 1 + src/controllers/cluster_group.rs | 1 + 10 files changed, 726 insertions(+), 15 deletions(-) create mode 100644 .dockerignore create mode 100644 src/api/fleet_bundle_deployment.rs diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6f9ab71 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +/target +_out/ \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 4c8a26c..110db16 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,7 +6,7 @@ on: - "v*.*.*" env: - TAG: ${{ github.ref_name }} + IMAGE_NAME: ${{ github.repository }} REGISTRY: ghcr.io jobs: @@ -28,10 +28,17 @@ jobs: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build docker image - run: just TAG=${{ env.TAG }} build-base - - name: Push docker image - run: just TAG=${{ env.TAG }} docker-push + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} release: runs-on: ubuntu-latest permissions: diff --git a/Dockerfile b/Dockerfile index 1ba8510..a064f4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ -FROM cgr.dev/chainguard/static as build +FROM registry.suse.com/bci/rust:1.81 AS build LABEL org.opencontainers.image.source=https://github.com/rancher-sandbox/cluster-api-addon-provider-fleet -COPY --chown=nonroot:nonroot ./_out/controller /app/ +COPY --chown=nonroot:nonroot ./ /src/ +WORKDIR /src +ARG features="" +RUN --mount=type=cache,target=/root/.cargo cargo build --features=${features} --release --bin controller -FROM alpine/helm:3.14.4 -COPY --from=build --chown=nonroot:nonroot /app/controller /apps/ +FROM registry.suse.com/suse/helm:3.13 +COPY --from=build --chown=nonroot:nonroot /src/target/release/controller /apps/controller ENV PATH="${PATH}:/apps" EXPOSE 8080 ENTRYPOINT ["/apps/controller"] diff --git a/metadata.yaml b/metadata.yaml index 33aa11c..df9e5a9 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -9,3 +9,6 @@ releaseSeries: - major: 0 minor: 3 contract: v1beta1 + - major: 0 + minor: 4 + contract: v1beta1 diff --git a/src/api/fleet_bundle_deployment.rs b/src/api/fleet_bundle_deployment.rs new file mode 100644 index 0000000..bc21fd2 --- /dev/null +++ b/src/api/fleet_bundle_deployment.rs @@ -0,0 +1,693 @@ +// WARNING: generated by kopium - manual changes will be overwritten +// kopium command: kopium -D Default -A -d -f - +// kopium version: 0.20.1 + +#[allow(unused_imports)] +mod prelude { + pub use kube::CustomResource; + pub use schemars::JsonSchema; + pub use serde::{Serialize, Deserialize}; + pub use std::collections::BTreeMap; + pub use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition; +} +use self::prelude::*; + +#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +#[kube(group = "fleet.cattle.io", version = "v1alpha1", kind = "BundleDeployment", plural = "bundledeployments")] +#[kube(namespaced)] +#[kube(status = "BundleDeploymentStatus")] +#[kube(derive="Default")] +pub struct BundleDeploymentSpec { + /// CorrectDrift specifies how drift correction should work. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "correctDrift")] + pub correct_drift: Option, + /// DependsOn refers to the bundles which must be ready before this bundle can be deployed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "dependsOn")] + pub depends_on: Option>, + /// DeploymentID is the ID of the currently applied deployment. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "deploymentID")] + pub deployment_id: Option, + /// OCIContents is true when this deployment's contents is stored in an oci registry + #[serde(default, skip_serializing_if = "Option::is_none", rename = "ociContents")] + pub oci_contents: Option, + /// Options are the deployment options, that are currently applied. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, + /// Paused if set to true, will stop any BundleDeployments from being + /// updated. If true, BundleDeployments will be marked as out of sync + /// when changes are detected. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub paused: Option, + /// StagedDeploymentID is the ID of the staged deployment. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "stagedDeploymentID")] + pub staged_deployment_id: Option, + /// StagedOptions are the deployment options, that are staged for + /// the next deployment. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "stagedOptions")] + pub staged_options: Option, +} + +/// CorrectDrift specifies how drift correction should work. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentCorrectDrift { + /// Enabled correct drift if true. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub enabled: Option, + /// Force helm rollback with --force option will be used if true. This will try to recreate all resources in the release. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub force: Option, + /// KeepFailHistory keeps track of failed rollbacks in the helm history. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "keepFailHistory")] + pub keep_fail_history: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentDependsOn { + /// Name of the bundle. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Selector matching bundle's labels. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub selector: Option, +} + +/// Selector matching bundle's labels. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentDependsOnSelector { + /// matchExpressions is a list of label selector requirements. The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchExpressions")] + pub match_expressions: Option>, + /// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + /// map is equivalent to an element of matchExpressions, whose key field is "key", the + /// operator is "In", and the values array contains only "value". The requirements are ANDed. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "matchLabels")] + pub match_labels: Option>, +} + +/// A label selector requirement is a selector that contains values, a key, and an operator that +/// relates the key and values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentDependsOnSelectorMatchExpressions { + /// key is the label key that the selector applies to. + pub key: String, + /// operator represents a key's relationship to a set of values. + /// Valid operators are In, NotIn, Exists and DoesNotExist. + pub operator: String, + /// values is an array of string values. If the operator is In or NotIn, + /// the values array must be non-empty. If the operator is Exists or DoesNotExist, + /// the values array must be empty. This array is replaced during a strategic + /// merge patch. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, +} + +/// Options are the deployment options, that are currently applied. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptions { + /// CorrectDrift specifies how drift correction should work. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "correctDrift")] + pub correct_drift: Option, + /// DefaultNamespace is the namespace to use for resources that do not + /// specify a namespace. This field is not used to enforce or lock down + /// the deployment to a specific namespace. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultNamespace")] + pub default_namespace: Option, + /// DeleteCRDResources deletes CRDs. Warning! this will also delete all your Custom Resources. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "deleteCRDResources")] + pub delete_crd_resources: Option, + /// DeleteNamespace can be used to delete the deployed namespace when removing the bundle + #[serde(default, skip_serializing_if = "Option::is_none", rename = "deleteNamespace")] + pub delete_namespace: Option, + /// Diff can be used to ignore the modified state of objects which are amended at runtime. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub diff: Option, + /// ForceSyncGeneration is used to force a redeployment + #[serde(default, skip_serializing_if = "Option::is_none", rename = "forceSyncGeneration")] + pub force_sync_generation: Option, + /// Helm options for the deployment, like the chart name, repo and values. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub helm: Option, + /// IgnoreOptions can be used to ignore fields when monitoring the bundle. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ignore: Option, + /// KeepResources can be used to keep the deployed resources when removing the bundle + #[serde(default, skip_serializing_if = "Option::is_none", rename = "keepResources")] + pub keep_resources: Option, + /// Kustomize options for the deployment, like the dir containing the + /// kustomization.yaml file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kustomize: Option, + /// TargetNamespace if present will assign all resource to this + /// namespace and if any cluster scoped resource exists the deployment + /// will fail. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + /// NamespaceAnnotations are annotations that will be appended to the namespace created by Fleet. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "namespaceAnnotations")] + pub namespace_annotations: Option>, + /// NamespaceLabels are labels that will be appended to the namespace created by Fleet. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "namespaceLabels")] + pub namespace_labels: Option>, + /// ServiceAccount which will be used to perform this deployment. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAccount")] + pub service_account: Option, + /// YAML options, if using raw YAML these are names that map to + /// overlays/{name} files that will be used to replace or patch a resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub yaml: Option, +} + +/// CorrectDrift specifies how drift correction should work. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsCorrectDrift { + /// Enabled correct drift if true. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub enabled: Option, + /// Force helm rollback with --force option will be used if true. This will try to recreate all resources in the release. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub force: Option, + /// KeepFailHistory keeps track of failed rollbacks in the helm history. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "keepFailHistory")] + pub keep_fail_history: Option, +} + +/// Diff can be used to ignore the modified state of objects which are amended at runtime. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsDiff { + /// ComparePatches match a resource and remove fields from the check for modifications. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "comparePatches")] + pub compare_patches: Option>, +} + +/// ComparePatch matches a resource and removes fields from the check for modifications. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsDiffComparePatches { + /// APIVersion is the apiVersion of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiVersion")] + pub api_version: Option, + /// JSONPointers ignore diffs at a certain JSON path. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jsonPointers")] + pub json_pointers: Option>, + /// Kind is the kind of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Namespace is the namespace of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + /// Operations remove a JSON path from the resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operations: Option>, +} + +/// Operation of a ComparePatch, usually "remove". +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsDiffComparePatchesOperations { + /// Op is usually "remove" + #[serde(default, skip_serializing_if = "Option::is_none")] + pub op: Option, + /// Path is the JSON path to remove. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub path: Option, + /// Value is usually empty. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +/// Helm options for the deployment, like the chart name, repo and values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsHelm { + /// Atomic sets the --atomic flag when Helm is performing an upgrade + #[serde(default, skip_serializing_if = "Option::is_none")] + pub atomic: Option, + /// Chart can refer to any go-getter URL or OCI registry based helm + /// chart URL. The chart will be downloaded. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub chart: Option, + /// DisableDNS can be used to customize Helm's EnableDNS option, which Fleet sets to `true` by default. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableDNS")] + pub disable_dns: Option, + /// DisableDependencyUpdate allows skipping chart dependencies update + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableDependencyUpdate")] + pub disable_dependency_update: Option, + /// DisablePreProcess disables template processing in values + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disablePreProcess")] + pub disable_pre_process: Option, + /// Force allows to override immutable resources. This could be dangerous. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub force: Option, + /// MaxHistory limits the maximum number of revisions saved per release by Helm. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxHistory")] + pub max_history: Option, + /// ReleaseName sets a custom release name to deploy the chart as. If + /// not specified a release name will be generated by combining the + /// invoking GitRepo.name + GitRepo.path. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "releaseName")] + pub release_name: Option, + /// Repo is the name of the HTTPS helm repo to download the chart from. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub repo: Option, + /// SkipSchemaValidation allows skipping schema validation against the chart values + #[serde(default, skip_serializing_if = "Option::is_none", rename = "skipSchemaValidation")] + pub skip_schema_validation: Option, + /// TakeOwnership makes helm skip the check for its own annotations + #[serde(default, skip_serializing_if = "Option::is_none", rename = "takeOwnership")] + pub take_ownership: Option, + /// TimeoutSeconds is the time to wait for Helm operations. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "timeoutSeconds")] + pub timeout_seconds: Option, + /// Values passed to Helm. It is possible to specify the keys and values + /// as go template strings. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, + /// ValuesFiles is a list of files to load values from. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "valuesFiles")] + pub values_files: Option>, + /// ValuesFrom loads the values from configmaps and secrets. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "valuesFrom")] + pub values_from: Option>, + /// Version of the chart to download + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, + /// WaitForJobs if set and timeoutSeconds provided, will wait until all + /// Jobs have been completed before marking the GitRepo as ready. It + /// will wait for as long as timeoutSeconds + #[serde(default, skip_serializing_if = "Option::is_none", rename = "waitForJobs")] + pub wait_for_jobs: Option, +} + +/// Define helm values that can come from configmap, secret or external. Credit: https://github.com/fluxcd/helm-operator/blob/0cfea875b5d44bea995abe7324819432070dfbdc/pkg/apis/helm.fluxcd.io/v1/types_helmrelease.go#L439 +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsHelmValuesFrom { + /// The reference to a config map with release values. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "configMapKeyRef")] + pub config_map_key_ref: Option, + /// The reference to a secret with release values. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretKeyRef")] + pub secret_key_ref: Option, +} + +/// The reference to a config map with release values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsHelmValuesFromConfigMapKeyRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + /// Name of a resource in the same namespace as the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// The reference to a secret with release values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsHelmValuesFromSecretKeyRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + /// Name of a resource in the same namespace as the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// IgnoreOptions can be used to ignore fields when monitoring the bundle. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsIgnore { + /// Conditions is a list of conditions to be ignored when monitoring the Bundle. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>>, +} + +/// Kustomize options for the deployment, like the dir containing the +/// kustomization.yaml file. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsKustomize { + /// Dir points to a custom folder for kustomize resources. This folder must contain + /// a kustomization.yaml file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub dir: Option, +} + +/// YAML options, if using raw YAML these are names that map to +/// overlays/{name} files that will be used to replace or patch a resource. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentOptionsYaml { + /// Overlays is a list of names that maps to folders in "overlays/". + /// If you wish to customize the file ./subdir/resource.yaml then a file + /// ./overlays/myoverlay/subdir/resource.yaml will replace the base + /// file. + /// A file named ./overlays/myoverlay/subdir/resource_patch.yaml will patch the base file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub overlays: Option>, +} + +/// StagedOptions are the deployment options, that are staged for +/// the next deployment. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptions { + /// CorrectDrift specifies how drift correction should work. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "correctDrift")] + pub correct_drift: Option, + /// DefaultNamespace is the namespace to use for resources that do not + /// specify a namespace. This field is not used to enforce or lock down + /// the deployment to a specific namespace. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "defaultNamespace")] + pub default_namespace: Option, + /// DeleteCRDResources deletes CRDs. Warning! this will also delete all your Custom Resources. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "deleteCRDResources")] + pub delete_crd_resources: Option, + /// DeleteNamespace can be used to delete the deployed namespace when removing the bundle + #[serde(default, skip_serializing_if = "Option::is_none", rename = "deleteNamespace")] + pub delete_namespace: Option, + /// Diff can be used to ignore the modified state of objects which are amended at runtime. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub diff: Option, + /// ForceSyncGeneration is used to force a redeployment + #[serde(default, skip_serializing_if = "Option::is_none", rename = "forceSyncGeneration")] + pub force_sync_generation: Option, + /// Helm options for the deployment, like the chart name, repo and values. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub helm: Option, + /// IgnoreOptions can be used to ignore fields when monitoring the bundle. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ignore: Option, + /// KeepResources can be used to keep the deployed resources when removing the bundle + #[serde(default, skip_serializing_if = "Option::is_none", rename = "keepResources")] + pub keep_resources: Option, + /// Kustomize options for the deployment, like the dir containing the + /// kustomization.yaml file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kustomize: Option, + /// TargetNamespace if present will assign all resource to this + /// namespace and if any cluster scoped resource exists the deployment + /// will fail. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + /// NamespaceAnnotations are annotations that will be appended to the namespace created by Fleet. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "namespaceAnnotations")] + pub namespace_annotations: Option>, + /// NamespaceLabels are labels that will be appended to the namespace created by Fleet. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "namespaceLabels")] + pub namespace_labels: Option>, + /// ServiceAccount which will be used to perform this deployment. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "serviceAccount")] + pub service_account: Option, + /// YAML options, if using raw YAML these are names that map to + /// overlays/{name} files that will be used to replace or patch a resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub yaml: Option, +} + +/// CorrectDrift specifies how drift correction should work. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsCorrectDrift { + /// Enabled correct drift if true. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub enabled: Option, + /// Force helm rollback with --force option will be used if true. This will try to recreate all resources in the release. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub force: Option, + /// KeepFailHistory keeps track of failed rollbacks in the helm history. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "keepFailHistory")] + pub keep_fail_history: Option, +} + +/// Diff can be used to ignore the modified state of objects which are amended at runtime. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsDiff { + /// ComparePatches match a resource and remove fields from the check for modifications. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "comparePatches")] + pub compare_patches: Option>, +} + +/// ComparePatch matches a resource and removes fields from the check for modifications. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsDiffComparePatches { + /// APIVersion is the apiVersion of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiVersion")] + pub api_version: Option, + /// JSONPointers ignore diffs at a certain JSON path. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "jsonPointers")] + pub json_pointers: Option>, + /// Kind is the kind of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Name is the name of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Namespace is the namespace of the resource to match. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + /// Operations remove a JSON path from the resource. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub operations: Option>, +} + +/// Operation of a ComparePatch, usually "remove". +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsDiffComparePatchesOperations { + /// Op is usually "remove" + #[serde(default, skip_serializing_if = "Option::is_none")] + pub op: Option, + /// Path is the JSON path to remove. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub path: Option, + /// Value is usually empty. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +/// Helm options for the deployment, like the chart name, repo and values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsHelm { + /// Atomic sets the --atomic flag when Helm is performing an upgrade + #[serde(default, skip_serializing_if = "Option::is_none")] + pub atomic: Option, + /// Chart can refer to any go-getter URL or OCI registry based helm + /// chart URL. The chart will be downloaded. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub chart: Option, + /// DisableDNS can be used to customize Helm's EnableDNS option, which Fleet sets to `true` by default. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableDNS")] + pub disable_dns: Option, + /// DisableDependencyUpdate allows skipping chart dependencies update + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disableDependencyUpdate")] + pub disable_dependency_update: Option, + /// DisablePreProcess disables template processing in values + #[serde(default, skip_serializing_if = "Option::is_none", rename = "disablePreProcess")] + pub disable_pre_process: Option, + /// Force allows to override immutable resources. This could be dangerous. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub force: Option, + /// MaxHistory limits the maximum number of revisions saved per release by Helm. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "maxHistory")] + pub max_history: Option, + /// ReleaseName sets a custom release name to deploy the chart as. If + /// not specified a release name will be generated by combining the + /// invoking GitRepo.name + GitRepo.path. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "releaseName")] + pub release_name: Option, + /// Repo is the name of the HTTPS helm repo to download the chart from. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub repo: Option, + /// SkipSchemaValidation allows skipping schema validation against the chart values + #[serde(default, skip_serializing_if = "Option::is_none", rename = "skipSchemaValidation")] + pub skip_schema_validation: Option, + /// TakeOwnership makes helm skip the check for its own annotations + #[serde(default, skip_serializing_if = "Option::is_none", rename = "takeOwnership")] + pub take_ownership: Option, + /// TimeoutSeconds is the time to wait for Helm operations. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "timeoutSeconds")] + pub timeout_seconds: Option, + /// Values passed to Helm. It is possible to specify the keys and values + /// as go template strings. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub values: Option>, + /// ValuesFiles is a list of files to load values from. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "valuesFiles")] + pub values_files: Option>, + /// ValuesFrom loads the values from configmaps and secrets. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "valuesFrom")] + pub values_from: Option>, + /// Version of the chart to download + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, + /// WaitForJobs if set and timeoutSeconds provided, will wait until all + /// Jobs have been completed before marking the GitRepo as ready. It + /// will wait for as long as timeoutSeconds + #[serde(default, skip_serializing_if = "Option::is_none", rename = "waitForJobs")] + pub wait_for_jobs: Option, +} + +/// Define helm values that can come from configmap, secret or external. Credit: https://github.com/fluxcd/helm-operator/blob/0cfea875b5d44bea995abe7324819432070dfbdc/pkg/apis/helm.fluxcd.io/v1/types_helmrelease.go#L439 +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsHelmValuesFrom { + /// The reference to a config map with release values. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "configMapKeyRef")] + pub config_map_key_ref: Option, + /// The reference to a secret with release values. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "secretKeyRef")] + pub secret_key_ref: Option, +} + +/// The reference to a config map with release values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsHelmValuesFromConfigMapKeyRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + /// Name of a resource in the same namespace as the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// The reference to a secret with release values. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsHelmValuesFromSecretKeyRef { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub key: Option, + /// Name of a resource in the same namespace as the referent. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + +/// IgnoreOptions can be used to ignore fields when monitoring the bundle. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsIgnore { + /// Conditions is a list of conditions to be ignored when monitoring the Bundle. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>>, +} + +/// Kustomize options for the deployment, like the dir containing the +/// kustomization.yaml file. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsKustomize { + /// Dir points to a custom folder for kustomize resources. This folder must contain + /// a kustomization.yaml file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub dir: Option, +} + +/// YAML options, if using raw YAML these are names that map to +/// overlays/{name} files that will be used to replace or patch a resource. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStagedOptionsYaml { + /// Overlays is a list of names that maps to folders in "overlays/". + /// If you wish to customize the file ./subdir/resource.yaml then a file + /// ./overlays/myoverlay/subdir/resource.yaml will replace the base + /// file. + /// A file named ./overlays/myoverlay/subdir/resource_patch.yaml will patch the base file. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub overlays: Option>, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "appliedDeploymentID")] + pub applied_deployment_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub conditions: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub display: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "modifiedStatus")] + pub modified_status: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nonModified")] + pub non_modified: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "nonReadyStatus")] + pub non_ready_status: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ready: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub release: Option, + /// Resources lists the metadata of resources that were deployed + /// according to the helm release history. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resources: Option>, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "syncGeneration")] + pub sync_generation: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatusDisplay { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub deployed: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub monitored: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub state: Option, +} + +/// ModifiedStatus is used to report the status of a resource that is modified. +/// It indicates if the modification was a create, a delete or a patch. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatusModifiedStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiVersion")] + pub api_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub delete: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub missing: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub patch: Option, +} + +/// NonReadyStatus is used to report the status of a resource that is not ready. It includes a summary. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatusNonReadyStatus { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiVersion")] + pub api_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub summary: Option, + /// UID is a type that holds unique ID values, including UUIDs. Because we + /// don't ONLY use UUIDs, this is an alias to string. Being a type captures + /// intent and helps make sure that UIDs and names do not get conflated. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub uid: Option, +} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatusNonReadyStatusSummary { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub message: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub state: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub transitioning: Option, +} + +/// BundleDeploymentResource contains the metadata of a deployed resource. +#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)] +pub struct BundleDeploymentStatusResources { + #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiVersion")] + pub api_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", rename = "createdAt")] + pub created_at: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, +} + diff --git a/src/api/fleet_cluster.rs b/src/api/fleet_cluster.rs index 724d868..811cf4c 100644 --- a/src/api/fleet_cluster.rs +++ b/src/api/fleet_cluster.rs @@ -25,10 +25,10 @@ pub struct ClusterSpecProxy { pub proxy: ClusterSpec, } -impl Into for ClusterSpec { - fn into(self) -> ClusterSpecProxy { +impl From for ClusterSpecProxy { + fn from(val: ClusterSpec) -> Self { ClusterSpecProxy{ - proxy: self, + proxy: val, } } } diff --git a/src/api/fleet_clustergroup.rs b/src/api/fleet_clustergroup.rs index 70b3b0f..a45488e 100644 --- a/src/api/fleet_clustergroup.rs +++ b/src/api/fleet_clustergroup.rs @@ -24,8 +24,8 @@ pub struct ClusterGroupProxy { pub proxy: ClusterGroupSpec, } -impl Into for ClusterGroupSpec { - fn into(self) -> ClusterGroupProxy { - ClusterGroupProxy { proxy: self } +impl From for ClusterGroupProxy { + fn from(val: ClusterGroupSpec) -> Self { + ClusterGroupProxy { proxy: val } } } diff --git a/src/controllers/cluster.rs b/src/controllers/cluster.rs index 219269c..7b91c27 100644 --- a/src/controllers/cluster.rs +++ b/src/controllers/cluster.rs @@ -131,6 +131,7 @@ impl Cluster { } impl FleetBundle for FleetClusterBundle { + #[allow(refining_impl_trait)] async fn sync(&self, ctx: Arc) -> ClusterSyncResult { match self.config.cluster_patch_enabled() { true => patch(ctx.clone(), self.fleet.clone()).await?, diff --git a/src/controllers/cluster_class.rs b/src/controllers/cluster_class.rs index 3f0a0e2..87d2127 100644 --- a/src/controllers/cluster_class.rs +++ b/src/controllers/cluster_class.rs @@ -55,6 +55,7 @@ impl From<&ClusterClass> for ClusterGroup { } impl FleetBundle for FleetClusterClassBundle { + #[allow(refining_impl_trait)] async fn sync(&self, ctx: Arc) -> GroupSyncResult { match self.config.cluster_class_patch_enabled() { true => patch(ctx, self.fleet_group.clone()).await?, diff --git a/src/controllers/cluster_group.rs b/src/controllers/cluster_group.rs index 28aa153..1979958 100644 --- a/src/controllers/cluster_group.rs +++ b/src/controllers/cluster_group.rs @@ -9,6 +9,7 @@ use super::{BundleResult, GroupSyncResult}; impl FleetBundle for ClusterGroup { // Applies finalizer on the existing ClusterGroup object, so the deletion event is not missed + #[allow(refining_impl_trait)] async fn sync(&self, ctx: Arc) -> GroupSyncResult { patch(ctx.clone(), self.clone()).await?;