blob: f0c7f646f8a96f3a8920ac10dd33090894cf8fe7 [file] [log] [blame]
#######################################################################################
# Copyright ETSI Contributors and Others.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#######################################################################################
# Module with custom functions to manage the transformations and generations associated to the different types of Building Blocks supported by OSM.
#
# Supported Brick types are:
#
# - `basic`. Basic transformation of the ResourceList. It performs a cleanup and regularization of the target Kustomization (enforce the right path in the repo, ensure that `wait` is enabled, etc.), unless specified otherwise. In addition, it also supports the commonest transformations for a Kustomization, such as addition of optional components, extra labels and/or annotations, hot replacement of image names and tags, etc. For more details, check out the help for the `brick transform basic` command.
# - `helmreleaseset`. Transformations for a ResourceList with a set of HelmReleases, so that values injected into the specific HelmReleases. It is a superset of the `basic` Brick, and its transformations are applied right after the corresponding basic transformations. For more details, check out the help for the `brick transform helmreleaseset` command.
# - `custom`. Transformation of the ResourceList with a custom (user-provided) "create" transformation after a `basic` regularization is applied. For more details, check out the help for the `custom create` command.
# - `custom-hr`. Transformation of the ResourceList with a custom (user-provided) "create" transformation after a `helmreleaseset` transformation (including `basic` regularizations) is applied. For more details, check out the help for the `custom create` command.
# - `custom-full`. Transformation of the ResourceList with a custom (user-provided) "create" transformation. **No `basic` regularization is applied**, so any regularization (if needed) should be implemented in the custom command. For more details, check out the help for the `custom create` command.
use ../krm *
use ./location.nu
use custom
# Apply the `basic` transformation to ResourceList received from stdin according to the specification of the Brick.
# The `basic` Brick transformation just does a cleanup and regularization of the target Kustomization
export def "transform basic" [
brick: record # Brick specification
]: [
record -> record
] {
let rl: record = $in
# Get the key parts
let brick_name: string = ($brick | get -i name | default "untitled-brick")
let kustomization_name: string = ($brick | get $.kustomization.name)
let kustomization_namespace: string = ($brick | get -i $.kustomization.namespace | default "flux-system")
let src: string = ($brick | get source | location from base path)
let options: record = ($brick | get -i options | default {})
## Should it avoid path regularization?
let keep_path: bool = ($options | get -i keep-path | default false)
## Should it avoid enforcing the wait?
let enforce_wait: bool = ($options | get -i enforce-wait | default true)
## Should it avoid enforcing the prune?
let enforce_prune: bool = ($options | get -i enforce-prune | default true)
## Should it enable (or append) some `components`?
let components: list = ($options | get -i components | default [])
## Should it set or overwrite `targetNamespace`?
let targetNamespace: string = ($options | get -i targetNamespace | default "")
## Should it overwrite `interval`?
let interval: string = ($options | get -i interval | default "")
## Should it set or overwrite `retryInterval`?
let retryInterval: string = ($options | get -i retryInterval | default "")
## Should it set or overwrite `serviceAccountName`?
let serviceAccountName: string = ($options | get -i serviceAccountName | default "")
## Should it add custom `healthChecks`?
let healthChecks: list = ($options | get -i healthChecks | default [])
## Should it add custom `healthCheckExprs`?
let healthCheckExprs: list = ($options | get -i healthCheckExprs | default [])
## Should it set or overwrite a `namePrefix`?
let namePrefix: string = ($options | get -i namePrefix | default "")
## Should it set or overwrite a `nameSuffix`?
let nameSuffix: string = ($options | get -i nameSuffix | default "")
## Should it append additional `.metadata.labels` and `.spec.commonMetadata.labels`?
let new_labels: record = ($options | get -i new_labels | default {})
## Should it append additional `.metadata.annotations` and `.spec.commonMetadata.annotations`?
let new_annotations: record = ($options | get -i new_annotations | default {})
## Should it append additional `.spec.images` replacements?
let images: list = ($options | get -i images | default [])
# Transform as per the basic Brick model
$rl
# Path regularization, if applicable
| if $keep_path { $in } else {
$in
| (
patch resource update key
$.spec.path $src
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
}
# Enforce the wait, if applicable
| if $enforce_wait {
$in
| (
patch resource upsert key
$.spec.wait $enforce_wait
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enforce the prune, if applicable
| if $enforce_prune {
$in
| (
patch resource upsert key
$.spec.prune $enforce_prune
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `components`, if applicable
| if ($components | is-not-empty) {
let tmp_rl: record = $in
let existing_components: list = (
$tmp_rl
| (
patch resource keep
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
| get -i $.items.0.spec.components
| default []
)
let all_components: list = ($existing_components ++ $components) | uniq
$tmp_rl
| (
patch resource upsert key
$.spec.components $all_components
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Set or overwrite `targetNamespace`, if applicable
| if ($targetNamespace | is-not-empty) {
$in
| (
patch resource upsert key
$.spec.targetNamespace $targetNamespace
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Overwrite `interval`, if applicable
| if ($interval | is-not-empty) {
$in
| (
patch resource update key
$.spec.interval $interval
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Set or overwrite `retryInterval`, if applicable
| if ($retryInterval | is-not-empty) {
$in
| (
patch resource upsert key
$.spec.retryInterval $retryInterval
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Set or overwrite `serviceAccountName`, if applicable
| if ($serviceAccountName | is-not-empty) {
$in
| (
patch resource upsert key
$.spec.serviceAccountName $serviceAccountName
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `healthChecks`, if applicable
| if ($healthChecks | is-not-empty) {
let tmp_rl: record = $in
let existing_healthChecks: list = ($tmp_rl | get -i $.spec.healthChecks | default [])
let all_healthChecks: list = ($existing_healthChecks ++ $healthChecks) | uniq
$tmp_rl
| (
patch resource upsert key
$.spec.healthChecks $all_healthChecks
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `healthCheckExprs`, if applicable
| if ($healthCheckExprs | is-not-empty) {
let tmp_rl: record = $in
let existing_healthCheckExprs: list = ($tmp_rl | get -i $.spec.healthCheckExprs | default [])
let all_healthCheckExprs: list = ($existing_healthCheckExprs ++ $healthCheckExprs) | uniq
$tmp_rl
| (
patch resource upsert key
$.spec.healthCheckExprs $all_healthCheckExprs
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Set or overwrite `namePrefix`, if applicable
| if ($namePrefix | is-not-empty) {
$in
| (
patch resource upsert key
$.spec.namePrefix $namePrefix
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Set or overwrite `nameSuffix`, if applicable
| if ($nameSuffix | is-not-empty) {
$in
| (
patch resource upsert key
$.spec.nameSuffix $nameSuffix
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `.metadata.labels` and `.spec.commonMetadata.labels`, if applicable
| if ($new_labels | is-not-empty) {
let tmp_rl: record = $in
let existing_labels: list = ($tmp_rl | get -i $.metadata.labels | default [])
let existing_common_labels: list = ($tmp_rl | get -i $.spec.commonMetadata.labels | default [])
let all_labels: list = ($existing_labels | merge $new_labels)
let all_common_labels: list = ($existing_common_labels | merge $new_labels)
$tmp_rl
| (
patch resource upsert key
$.metadata.labels
$all_labels
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
| (
patch resource upsert key
$.spec.commonMetadata.labels
$all_common_labels
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `.metadata.annotations` and `.spec.commonMetadata.annotations`, if applicable
| if ($new_annotations | is-not-empty) {
let tmp_rl: record = $in
let existing_annotations: list = ($tmp_rl | get -i $.metadata.annotations | default [])
let existing_common_annotations: list = ($tmp_rl | get -i $.spec.commonMetadata.annotations | default [])
let all_annotations: list = ($existing_annotations | merge $new_annotations)
let all_common_annotations: list = ($existing_common_annotations | merge $new_annotations)
$tmp_rl
| (
patch resource upsert key
$.metadata.annotations
$all_annotations
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
| (
patch resource upsert key
$.spec.commonMetadata.annotations
$all_common_annotations
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
# Enable (or append) some `.spec.images` replacements, if applicable
| if ($images | is-not-empty) {
let tmp_rl: record = $in
let existing_images: list = ($tmp_rl | get -i $.spec.images | default [])
let all_images: list = ($existing_images ++ $images) | uniq
$tmp_rl
| (
patch resource upsert key
$.spec.images $all_images
"kustomize.toolkit.fluxcd.io/v1" Kustomization $kustomization_name $kustomization_namespace
)
} else { $in }
}
# Apply the `helmreleaseset` transformation to ResourceList received from stdin according to the specification of the Brick.
# The `basic` Brick transformation just does a cleanup and regularization of the target Kustomization
export def "transform helmreleaseset" [
brick: record # Brick specification
]: [
record -> record
] {
# Input ReleaseList after basic transformations
let rl: record = $in
# Get the key parts
let brick_name: string = ($brick | get -i name | default "untitled-brick")
let kustomization_name: string = ($brick | get $.kustomization.name)
let kustomization_namespace: string = ($brick | get -i $.kustomization.namespace | default "flux-system")
let hrset_values: list<record> = ($brick | get "hrset-values" | default [])
let public_age_key: string = ($brick | get -i $.public-age-key | default "")
# Apply HelmRelease-specific transformations
$hrset_values
| reduce --fold $rl {|elt, acc|
$acc
| (
overlaypatch helmrelease set values
# --ks-namespace: string
--ks-namespace $kustomization_namespace
# --hr-namespace: string
--hr-namespace ($elt | get $.HelmRelease.namespace)
# --operation: string = "add"
# --cm-key: string = "values.yaml"
--cm-key ($elt | get -i $.valuesFrom.configMapKeyRef.key | default "values.yaml")
# --cm-target-path: string
# --cm-optional
# --create-cm-with-values: record
--create-cm-with-values ($elt | get -i "create-cm" | default {})
# --secret-key: string = "values.yaml"
--secret-key ($elt | get -i $.valuesFrom.secretKeyRef.key | default "values.yaml")
# --secret-target-path: string
# --secret-optional
# --create-secret-with-values: record
--create-secret-with-values (
$env
| get -i ($elt | get -i $.create-secret.env-values-reference | default "")
| default {}
)
# --public-age-key: string
--public-age-key $public_age_key
# kustomization_name: string
$kustomization_name
# helmrelease_name: string
($elt | get $.HelmRelease.name)
# inline_values?: record
($elt | get -i "inline-values" | default {})
# cm_name?: string
($elt | get -i $.valuesFrom.configMapKeyRef.name | default "")
# secret_name?: string
($elt | get -i $.valuesFrom.secretKeyRef.name | default "")
)
}
}
# Transform the ResourceList received from stdin according to the specification of a Brick transformation.
#
export def transform [
brick: record # Brick specification
environment: record = {} # Record with environment variables to load
]: [
record -> record
] {
# Get input ResourceList
let rl: record = $in
# Get the brick name
let brick_name: string = ($brick | get -i name | default "untitled-brick")
# Update the environment to include the brick name
let updated_environment: record = (
$environment
| upsert $.BRICK_NAME $brick_name
)
# Update the brick record accordingly
let updated_brick: record = (
$brick
| replace vars $updated_environment
)
# Get other key parts
let brick_type: string = ($updated_brick | get -i type | default "basic" | str downcase)
# Apply transformation according to the brick type
with-env $updated_environment {
match $brick_type {
"basic" => {
# Basic transformation of the ResourceList (just cleanup and regularization)
$rl
| transform basic $updated_brick
},
"helmreleaseset" => {
# Transformation of the ResourceList with a set of HelmReleases
$rl
| transform basic $updated_brick
| transform helmreleaseset $updated_brick
},
"custom-full" => {
# Transformation of the ResourceList with a custom "create" transformation
$rl
| custom brick create $updated_brick $updated_environment
},
"custom" => {
# Transformation of the ResourceList with a custom "create" transformation, after a basic cleanup and regularization
$rl
| transform basic $updated_brick
| custom brick create $updated_brick $updated_environment
},
"custom-hr" => {
# Transformation of the ResourceList with a custom "create" transformation, after a `helmreleaseset` transformation
$rl
| transform basic $updated_brick
| transform helmreleaseset $updated_brick
| custom brick create $updated_brick $updated_environment
},
_ => {
# Unknown brick type, throw an error
error make { msg: $"Error: Unknown Brick type: ($updated_brick | get type)" }
}
}
}
}