Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OCI Support #437

Merged
merged 43 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
efb69dc
Add Atmos custom commands
aknysh Oct 8, 2023
17a4668
Update Go and packages versions
aknysh Oct 8, 2023
6e6a5d8
Add Sprig functions support to Atmos vendoring Go templates
aknysh Oct 8, 2023
60e9da5
Update `context` in imports
aknysh Oct 8, 2023
31c2880
Update `context` in imports
aknysh Oct 8, 2023
995dd21
Update `context` in imports
aknysh Oct 8, 2023
e34d3ea
Update `context` in imports
aknysh Oct 8, 2023
25e5336
Update `context` in imports
aknysh Oct 8, 2023
6b832fa
Update `context` in imports
aknysh Oct 8, 2023
518244f
Add global `terraform.command` and `helmfile.command` sections
aknysh Oct 9, 2023
68fd6d6
Update `atmos terraform clean` command
aknysh Oct 9, 2023
9d8839f
Update Atmos help
aknysh Oct 9, 2023
90e9356
Update Atmos help
aknysh Oct 9, 2023
4cc6b00
Update Atmos help
aknysh Oct 9, 2023
d97cb34
Update Atmos help
aknysh Oct 9, 2023
d353860
Update Atmos help
aknysh Oct 9, 2023
5982a1c
Add OCI support to `atmos vendor`
aknysh Oct 10, 2023
15824d5
Add OCI support to `atmos vendor` command
aknysh Oct 10, 2023
616f26b
Add OCI support to `atmos vendor` command
aknysh Oct 10, 2023
aa92fe5
Add OCI support to `atmos vendor` command
aknysh Oct 10, 2023
e185177
Add OCI support to `atmos vendor` command
aknysh Oct 11, 2023
2f0a95f
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
f068271
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
ce34d32
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
ada1295
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
8182ad8
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
54ffd66
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
5c2b927
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
4029875
Add OCI support to `atmos vendor` command
aknysh Oct 12, 2023
f3976d0
Add OCI support to `atmos vendor` command
aknysh Oct 13, 2023
4c21223
Add examples of Rego policies for Atmos components and stacks validation
aknysh Oct 13, 2023
dc2ff12
Add examples of Rego policies for Atmos components and stacks validation
aknysh Oct 13, 2023
d5ab70e
Add examples of Rego policies for Atmos components and stacks validation
aknysh Oct 13, 2023
5a12a10
Add examples of Rego policies for Atmos components and stacks validation
aknysh Oct 13, 2023
3efab7a
Update internal/exec/oci_utils.go
aknysh Oct 13, 2023
13914b4
updates
aknysh Oct 13, 2023
c8ccaf7
Merge remote-tracking branch 'origin/new-features-2' into new-features-2
aknysh Oct 13, 2023
ae396a2
Update website/docs/core-concepts/components/component-validation.md
aknysh Oct 13, 2023
4ce6f79
updates
aknysh Oct 13, 2023
c94c09c
updates
aknysh Oct 13, 2023
bf7c34f
updates
aknysh Oct 13, 2023
fc010d7
updates
aknysh Oct 13, 2023
f527a1a
updates
aknysh Oct 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: 'Setup Go'
uses: actions/setup-go@v3
with:
go-version: '1.20'
go-version: '1.21'

# Print Go version
- run: go version
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: "1.20"
go-version: "1.21"
id: go

- name: Check out code into the Go module directory
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: "1.20"
go-version: "1.21"
id: go

- name: Check out code into the Go module directory
Expand Down
252 changes: 252 additions & 0 deletions atmos.yaml

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions cmd/cmd_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func executeCustomCommand(
// process the component stack config and expose it in {{ .ComponentConfig.xxx.yyy.zzz }} Go template variables
if commandConfig.ComponentConfig.Component != "" && commandConfig.ComponentConfig.Stack != "" {
// Process Go templates in the command's 'component_config.component'
component, err := u.ProcessTmpl(fmt.Sprintf("component-config-component-%d", i), commandConfig.ComponentConfig.Component, data)
component, err := u.ProcessTmpl(fmt.Sprintf("component-config-component-%d", i), commandConfig.ComponentConfig.Component, data, false)
if err != nil {
u.LogErrorAndExit(err)
}
Expand All @@ -179,7 +179,7 @@ func executeCustomCommand(
}

// Process Go templates in the command's 'component_config.stack'
stack, err := u.ProcessTmpl(fmt.Sprintf("component-config-stack-%d", i), commandConfig.ComponentConfig.Stack, data)
stack, err := u.ProcessTmpl(fmt.Sprintf("component-config-stack-%d", i), commandConfig.ComponentConfig.Stack, data, false)
if err != nil {
u.LogErrorAndExit(err)
}
Expand Down Expand Up @@ -221,7 +221,7 @@ func executeCustomCommand(
value = strings.TrimRight(res, "\r\n")
} else {
// Process Go templates in the values of the command's ENV vars
value, err = u.ProcessTmpl(fmt.Sprintf("env-var-%d", i), value, data)
value, err = u.ProcessTmpl(fmt.Sprintf("env-var-%d", i), value, data, false)
if err != nil {
u.LogErrorAndExit(err)
}
Expand All @@ -243,7 +243,7 @@ func executeCustomCommand(

// Process Go templates in the command's steps.
// Steps support Go templates and have access to {{ .ComponentConfig.xxx.yyy.zzz }} Go template variables
commandToRun, err := u.ProcessTmpl(fmt.Sprintf("step-%d", i), step, data)
commandToRun, err := u.ProcessTmpl(fmt.Sprintf("step-%d", i), step, data, false)
if err != nil {
u.LogErrorAndExit(err)
}
Expand Down
8 changes: 4 additions & 4 deletions examples/complete/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Geodesic: https://github.com/cloudposse/geodesic/
ARG GEODESIC_VERSION=2.2.4
ARG GEODESIC_VERSION=2.6.0
ARG GEODESIC_OS=debian

# atmos: https://github.com/cloudposse/atmos
ARG ATMOS_VERSION=1.45.0
ARG ATMOS_VERSION=1.46.0

# Terraform: https://github.com/hashicorp/terraform/releases
ARG TF_VERSION=1.5.6
ARG TF_VERSION=1.6.1

FROM cloudposse/geodesic:${GEODESIC_VERSION}-${GEODESIC_OS}

# Geodesic message of the Day
# Geodesic message of the day
ENV MOTD_URL="https://geodesic.sh/motd"

# Geodesic banner message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spec:
# In 'uri', Golang templates are supported https://pkg.go.dev/text/template
# If 'version' is provided, '{{.Version}}' will be replaced with the 'version' value before pulling the files from 'uri'
uri: github.com/cloudposse/terraform-aws-components.git//modules/account-map?ref={{.Version}}
version: 1.240.0
version: 1.315.1
# Only include the files that match the 'included_paths' patterns
# If 'included_paths' is not specified, all files will be matched except those that match the patterns from 'excluded_paths'
# 'included_paths' support POSIX-style Globs for file names/paths (double-star `**` is supported)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ spec:
# In 'uri', Golang templates are supported https://pkg.go.dev/text/template
# If 'version' is provided, '{{.Version}}' will be replaced with the 'version' value before pulling the files from 'uri'
uri: github.com/cloudposse/terraform-aws-components.git//modules/vpc-flow-logs-bucket?ref={{.Version}}
version: 1.240.0
version: 1.315.1
# Only include the files that match the 'included_paths' patterns
# If 'included_paths' is not specified, all files will be matched except those that match the patterns from 'excluded_paths'
# 'included_paths' support POSIX-style Globs for file names/paths (double-star `**` is supported)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ spec:
# In 'uri', Golang templates are supported https://pkg.go.dev/text/template
# If 'version' is provided, '{{.Version}}' will be replaced with the 'version' value before pulling the files from 'uri'
uri: github.com/cloudposse/terraform-aws-components.git//modules/vpc?ref={{.Version}}
version: 1.240.0
version: 1.315.1
# Only include the files that match the 'included_paths' patterns
# If 'included_paths' is not specified, all files will be matched except those that match the patterns from 'excluded_paths'
# 'included_paths' support POSIX-style Globs for file names/paths (double-star `**` is supported)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 'vpc2' component vendoring config
# This is an example of how to download a Terraform component from an OCI registry (https://opencontainers.org), e.g. AWS Public ECR

# 'component.yaml' in the component folder is processed by the 'atmos' commands
# 'atmos vendor pull -c infra/vpc2' or 'atmos vendor pull --component infra/vpc2'

apiVersion: atmos/v1
kind: ComponentVendorConfig
metadata:
name: vpc2-vendor-config
description: Config for vendoring of 'vpc2' component
spec:
source:
# Source 'uri' supports the following protocols: OCI (https://opencontainers.org), Git, Mercurial, HTTP, HTTPS, Amazon S3, Google GCP,
# and all URL and archive formats as described in https://github.com/hashicorp/go-getter
# In 'uri', Golang templates are supported https://pkg.go.dev/text/template
# If 'version' is provided, '{{.Version}}' will be replaced with the 'version' value before pulling the files from 'uri'
# Download the component from the AWS public ECR registry (https://docs.aws.amazon.com/AmazonECR/latest/public/public-registries.html)
uri: "oci://public.ecr.aws/cloudposse/components/terraform/stable/aws/vpc:{{.Version}}"
version: "latest"
# Only include the files that match the 'included_paths' patterns
# If 'included_paths' is not specified, all files will be matched except those that match the patterns from 'excluded_paths'
# 'included_paths' support POSIX-style Globs for file names/paths (double-star `**` is supported)
# https://en.wikipedia.org/wiki/Glob_(programming)
# https://github.com/bmatcuk/doublestar#patterns
included_paths:
- "**/*.*"
122 changes: 122 additions & 0 deletions examples/complete/stacks/schemas/opa/examples/example1.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# https://www.openpolicyagent.org/docs/v0.13.5/how-do-i-write-policies
# https://www.openpolicyagent.org/docs/latest/policy-language
# https://www.openpolicyagent.org/docs/latest/policy-reference
# https://www.openpolicyagent.org/docs/v0.12.2/language-reference/#regex

# 'atmos' looks for the 'errors' (array of strings) output from all OPA policies
# If the 'errors' output contains one or more error messages, 'atmos' considers the policy failed

# 'package atmos' is required in all 'atmos' OPA policies
package atmos

# Function `object_has_key` checks if an object has the specified key with a string value
# https://www.openpolicyagent.org/docs/latest/policy-reference/#types
object_has_key(o, k) {
some item
item = o[k]
type_name(item) == "string"
}

# Check the app hostname usign Regex
errors[message] {
not re_match("^([a-z0-9]+([\\-a-z0-9]*[a-z0-9]+)?\\.){1,}([a-z0-9]+([\\-a-z0-9]*[a-z0-9]+)?){1,63}(\\.[a-z0-9]{2,7})+$", input.vars.app_config.hostname)
message = "'app_config.hostname' must contain at least a subdomain and a top level domain. Example: subDomain1.topLevelDomain.com"
}

# Check the email address usign Regex
errors[message] {
not re_match("^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", input.vars.app_config.contact.email)
message = "'app_config.contact.email' must be a valid email address"
}

# Check the phone number usign Regex
errors[message] {
not re_match("^[\\+]?[(]?[0-9]{3}[)]?[-\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}", input.vars.app_config.contact.phone)
message = "'app_config.contact.phone' must be a valid phone number"
}

# Check if the component has a `Team` tag
errors[message] {
not object_has_key(input.vars.tags, "Team")
message = "All components must have 'Team' tag defined to specify which team is responsible for managing and provisioning them"
}

# Check if the Team has permissions to provision components in an OU (tenant)
errors[message] {
input.vars.tags.Team == "devs"
input.vars.tenant == "corp"
message = "'devs' team cannot provision components into 'corp' OU"
}

# Check the message of the day from the manager
# If `settings.notes.allowed` is set to `false`, output the message from the manager
errors[message] {
input.settings.notes.allowed == false
message = concat("", [input.settings.notes.manager, " says: ", input.settings.notes.message])
}

# Check `notes2` config in the free-form Atmos section `settings`
errors[message] {
input.settings.notes2.message == ""
message = "'notes2.message' should not be empty"
}

# Check that the `app_config.hostname` variable is defined only once for the stack accross all stack config files
# Refer to https://atmos.tools/cli/commands/describe/component#sources-of-component-variables for details on how 'atmos' detects sources for all variables
# https://www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all
errors[message] {
hostnames := {app_config | some app_config in input.sources.vars.app_config; app_config.hostname}
count(hostnames) > 0
message = "'app_config.hostname' variable must be defined only once for the stack accross all stack config files"
}

# This policy checks that the 'bar' variable is not defined in any of the '_defaults.yaml' Atmos stack config files
# Refer to https://atmos.tools/cli/commands/describe/component#sources-of-component-variables for details on how 'atmos' detects sources for all variables
# https://www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all
errors[message] {
# Get all 'stack_dependencies' of the 'bar' variable
stack_dependencies := input.sources.vars.bar.stack_dependencies
# Get all stack dependencies of the 'bar' variable where 'stack_file' ends with '_defaults'
defaults_stack_dependencies := {stack_dependency | some stack_dependency in stack_dependencies; endswith(stack_dependency.stack_file, "_defaults")}
# Check the count of the stack dependencies of the 'bar' variable where 'stack_file' ends with '_defaults'
count(defaults_stack_dependencies) > 0
# Generate the error message
message = "The 'bar' variable must not be defined in any of '_defaults.yaml' stack config files"
}

# This policy checks that if the 'foo' variable is defined in the 'stack1.yaml' stack config file, it cannot be overriden in 'stack2.yaml'
# Refer to https://atmos.tools/cli/commands/describe/component#sources-of-component-variables for details on how 'atmos' detects sources for all variables
# https://www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all
errors[message] {
# Get all 'stack_dependencies' of the 'foo' variable
stack_dependencies := input.sources.vars.foo.stack_dependencies
# Check if the 'foo' variable is defined in the 'stack1.yaml' stack config file
stack1_dependency := endswith(stack_dependencies[0].stack_file, "stack1")
stack1_dependency == true
# Get all stack dependencies of the 'foo' variable where 'stack_file' ends with 'stack2' (this means that the variable is redefined in one of the files 'stack2')
stack2_dependencies := {stack_dependency | some stack_dependency in stack_dependencies; endswith(stack_dependency.stack_file, "stack2")}
# Check the count of the stack dependencies of the 'foo' variable where 'stack_file' ends with 'stack2'
count(stack2_dependencies) > 0
# Generate the error message
message = "If the 'foo' variable is defined in 'stack1.yaml', it cannot be overriden in 'stack2.yaml'"
}

# This policy shows an example on how to check the imported files in the stacks
# All stack files (root stacks and imported) that the current component depends on are in the `deps` section
# For example:
# deps:
# - catalog/xxx
# - catalog/yyy
# - orgs/zzz/_defaults
errors[message] {
input.vars.tags.Team == "devs"
input.vars.tenant == "corp"
input.deps[_] == "catalog/xxx"
message = "'devs' team cannot import the 'catalog/xxx' file when provisioning components into 'corp' OU"
}

# Note:
# If a regex pattern in the 're_match' function contains a backslash to escape special chars (e.g. '\.' or '\-'),
# it must be escaped with another backslash when represented as a regular Go string ('\\.', '\\-').
# The reason is that backslash is also used to escape special characters in Go strings like newline (\n).
# If you want to match the backslash character itself, you'll need four slashes.