Merge pull request #512 from TomChv/buildkit-secrets

Buildkit secrets supports
This commit is contained in:
Andrea Luzzardi 2021-05-28 14:13:35 -07:00 committed by GitHub
commit 2f9a5df397
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 1078 additions and 659 deletions

View File

@ -82,11 +82,12 @@ jobs:
sudo curl -L -o /usr/local/bin/sops https://github.com/mozilla/sops/releases/download/v3.6.1/sops-v3.6.1.linux sudo curl -L -o /usr/local/bin/sops https://github.com/mozilla/sops/releases/download/v3.6.1/sops-v3.6.1.linux
sudo chmod +x /usr/local/bin/sops sudo chmod +x /usr/local/bin/sops
- name: Import PGP private key - name: Import Dagger private key
env: env:
SOPS_PGP_KEY: ${{ secrets.SOPS_PGP_KEY }} DAGGER_AGE_KEY: ${{ secrets.DAGGER_AGE_KEY }}
run: | run: |
echo "$SOPS_PGP_KEY" | base64 -d | gpg --import mkdir ~/.dagger
echo "$DAGGER_AGE_KEY" > ~/.dagger/keys.txt
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v1

View File

@ -2,7 +2,6 @@ package client
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -87,13 +86,13 @@ func (c *Client) Do(ctx context.Context, state *state.State, fn DoFunc) (*enviro
// Spawn build function // Spawn build function
eg.Go(func() error { eg.Go(func() error {
return c.buildfn(gctx, environment, fn, events) return c.buildfn(gctx, state, environment, fn, events)
}) })
return environment, eg.Wait() return environment, eg.Wait()
} }
func (c *Client) buildfn(ctx context.Context, env *environment.Environment, fn DoFunc, ch chan *bk.SolveStatus) error { func (c *Client) buildfn(ctx context.Context, st *state.State, env *environment.Environment, fn DoFunc, ch chan *bk.SolveStatus) error {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
// Scan local dirs to grant access // Scan local dirs to grant access
@ -109,10 +108,13 @@ func (c *Client) buildfn(ctx context.Context, env *environment.Environment, fn D
// buildkit auth provider (registry) // buildkit auth provider (registry)
auth := solver.NewRegistryAuthProvider() auth := solver.NewRegistryAuthProvider()
// secrets
secrets := solver.NewSecretsProvider(st)
// Setup solve options // Setup solve options
opts := bk.SolveOpt{ opts := bk.SolveOpt{
LocalDirs: localdirs, LocalDirs: localdirs,
Session: []session.Attachable{auth}, Session: []session.Attachable{auth, secrets},
} }
// Call buildkit solver // Call buildkit solver
@ -127,6 +129,7 @@ func (c *Client) buildfn(ctx context.Context, env *environment.Environment, fn D
Gateway: gw, Gateway: gw,
Events: ch, Events: ch,
Auth: auth, Auth: auth,
Secrets: secrets,
NoCache: c.noCache, NoCache: c.noCache,
}) })
@ -165,7 +168,7 @@ func (c *Client) buildfn(ctx context.Context, env *environment.Environment, fn D
return res, nil return res, nil
}, ch) }, ch)
if err != nil { if err != nil {
return fmt.Errorf("buildkit solve: %w", bkCleanError(err)) return solver.CleanError(err)
} }
for k, v := range resp.ExporterResponse { for k, v := range resp.ExporterResponse {
// FIXME consume exporter response // FIXME consume exporter response
@ -243,22 +246,3 @@ func (c *Client) logSolveStatus(ctx context.Context, ch chan *bk.SolveStatus) er
}, },
) )
} }
// A helper to remove noise from buildkit error messages.
// FIXME: Obviously a cleaner solution would be nice.
func bkCleanError(err error) error {
noise := []string{
"executor failed running ",
"buildkit-runc did not terminate successfully",
"rpc error: code = Unknown desc = ",
"failed to solve: ",
}
msg := err.Error()
for _, s := range noise {
msg = strings.ReplaceAll(msg, s, "")
}
return errors.New(msg)
}

View File

@ -44,7 +44,7 @@ func New(st *state.State) (*Environment, error) {
// Prepare inputs // Prepare inputs
for key, input := range st.Inputs { for key, input := range st.Inputs {
v, err := input.Compile(st) v, err := input.Compile(key, st)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -86,7 +86,7 @@ func (e *Environment) LoadPlan(ctx context.Context, s solver.Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "environment.LoadPlan") span, ctx := opentracing.StartSpanFromContext(ctx, "environment.LoadPlan")
defer span.Finish() defer span.Finish()
planSource, err := e.state.PlanSource().Compile(e.state) planSource, err := e.state.PlanSource().Compile("", e.state)
if err != nil { if err != nil {
return err return err
} }
@ -157,7 +157,7 @@ func (e *Environment) LocalDirs() map[string]string {
} }
// 2. Scan the plan // 2. Scan the plan
plan, err := e.state.PlanSource().Compile(e.state) plan, err := e.state.PlanSource().Compile("", e.state)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -490,6 +490,25 @@ func (p *Pipeline) mount(ctx context.Context, dest string, mnt *compiler.Value)
return nil, fmt.Errorf("invalid mount source: %q", s) return nil, fmt.Errorf("invalid mount source: %q", s)
} }
} }
// eg. mount: "/foo": secret: mysecret
if secret := mnt.Lookup("secret"); secret.Exists() {
if !secret.HasAttr("secret") {
return nil, fmt.Errorf("invalid secret %q: not a secret", secret.Path().String())
}
idValue := secret.Lookup("id")
if !idValue.Exists() {
return nil, fmt.Errorf("invalid secret %q: no id field", secret.Path().String())
}
id, err := idValue.String()
if err != nil {
return nil, fmt.Errorf("invalid secret id: %w", err)
}
return llb.AddSecret(dest,
llb.SecretID(id),
llb.SecretFileOpt(0, 0, 0400), // uid, gid, mask)
), nil
}
// eg. mount: "/foo": { from: www.source } // eg. mount: "/foo": { from: www.source }
from := NewPipeline(mnt.Lookup("from"), p.s) from := NewPipeline(mnt.Lookup("from"), p.s)
if err := from.Run(ctx); err != nil { if err := from.Run(ctx); err != nil {

47
solver/secretsprovider.go Normal file
View File

@ -0,0 +1,47 @@
package solver
import (
"context"
"strings"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/secrets"
"github.com/moby/buildkit/session/secrets/secretsprovider"
"github.com/rs/zerolog/log"
"go.dagger.io/dagger/state"
)
func NewSecretsProvider(st *state.State) session.Attachable {
return secretsprovider.NewSecretProvider(&inputStore{st})
}
type inputStore struct {
st *state.State
}
func (s *inputStore) GetSecret(ctx context.Context, id string) ([]byte, error) {
lg := log.Ctx(ctx)
const secretPrefix = "secret="
if !strings.HasPrefix(id, secretPrefix) {
return nil, secrets.ErrNotFound
}
id = strings.TrimPrefix(id, secretPrefix)
input, ok := s.st.Inputs[id]
if !ok {
return nil, secrets.ErrNotFound
}
if input.Secret == nil {
return nil, secrets.ErrNotFound
}
lg.
Debug().
Str("id", id).
Msg("injecting secret")
return []byte(input.Secret.PlainText()), nil
}

View File

@ -3,7 +3,9 @@ package solver
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"strings"
bk "github.com/moby/buildkit/client" bk "github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
@ -25,6 +27,7 @@ type Opts struct {
Gateway bkgw.Client Gateway bkgw.Client
Events chan *bk.SolveStatus Events chan *bk.SolveStatus
Auth *RegistryAuthProvider Auth *RegistryAuthProvider
Secrets session.Attachable
NoCache bool NoCache bool
} }
@ -100,7 +103,11 @@ func (s Solver) ResolveImageConfig(ctx context.Context, ref string, opts llb.Res
// Solve will block until the state is solved and returns a Reference. // Solve will block until the state is solved and returns a Reference.
func (s Solver) SolveRequest(ctx context.Context, req bkgw.SolveRequest) (*bkgw.Result, error) { func (s Solver) SolveRequest(ctx context.Context, req bkgw.SolveRequest) (*bkgw.Result, error) {
return s.opts.Gateway.Solve(ctx, req) res, err := s.opts.Gateway.Solve(ctx, req)
if err != nil {
return nil, CleanError(err)
}
return res, nil
} }
// Solve will block until the state is solved and returns a Reference. // Solve will block until the state is solved and returns a Reference.
@ -150,7 +157,7 @@ func (s Solver) Export(ctx context.Context, st llb.State, img *dockerfile2llb.Im
opts := bk.SolveOpt{ opts := bk.SolveOpt{
Exports: []bk.ExportEntry{output}, Exports: []bk.ExportEntry{output},
Session: []session.Attachable{s.opts.Auth}, Session: []session.Attachable{s.opts.Auth, s.opts.Secrets},
} }
ch := make(chan *bk.SolveStatus) ch := make(chan *bk.SolveStatus)
@ -204,3 +211,22 @@ func dumpLLB(def *bkpb.Definition) ([]byte, error) {
} }
return json.Marshal(ops) return json.Marshal(ops)
} }
// A helper to remove noise from buildkit error messages.
// FIXME: Obviously a cleaner solution would be nice.
func CleanError(err error) error {
noise := []string{
"executor failed running ",
"buildkit-runc did not terminate successfully",
"rpc error: code = Unknown desc = ",
"failed to solve: ",
}
msg := err.Error()
for _, s := range noise {
msg = strings.ReplaceAll(msg, s, "")
}
return errors.New(msg)
}

View File

@ -37,24 +37,24 @@ type Input struct {
File *fileInput `yaml:"file,omitempty"` File *fileInput `yaml:"file,omitempty"`
} }
func (i Input) Compile(state *State) (*compiler.Value, error) { func (i Input) Compile(key string, state *State) (*compiler.Value, error) {
switch { switch {
case i.Dir != nil: case i.Dir != nil:
return i.Dir.Compile(state) return i.Dir.Compile(key, state)
case i.Git != nil: case i.Git != nil:
return i.Git.Compile(state) return i.Git.Compile(key, state)
case i.Docker != nil: case i.Docker != nil:
return i.Docker.Compile(state) return i.Docker.Compile(key, state)
case i.Text != nil: case i.Text != nil:
return i.Text.Compile(state) return i.Text.Compile(key, state)
case i.Secret != nil: case i.Secret != nil:
return i.Secret.Compile(state) return i.Secret.Compile(key, state)
case i.JSON != nil: case i.JSON != nil:
return i.JSON.Compile(state) return i.JSON.Compile(key, state)
case i.YAML != nil: case i.YAML != nil:
return i.YAML.Compile(state) return i.YAML.Compile(key, state)
case i.File != nil: case i.File != nil:
return i.File.Compile(state) return i.File.Compile(key, state)
default: default:
return nil, fmt.Errorf("input has not been set") return nil, fmt.Errorf("input has not been set")
} }
@ -75,7 +75,7 @@ type dirInput struct {
Include []string `json:"include,omitempty"` Include []string `json:"include,omitempty"`
} }
func (dir dirInput) Compile(state *State) (*compiler.Value, error) { func (dir dirInput) Compile(_ string, state *State) (*compiler.Value, error) {
// FIXME: serialize an intermediate struct, instead of generating cue source // FIXME: serialize an intermediate struct, instead of generating cue source
// json.Marshal([]string{}) returns []byte("null"), which wreaks havoc // json.Marshal([]string{}) returns []byte("null"), which wreaks havoc
@ -122,7 +122,7 @@ func GitInput(remote, ref, dir string) Input {
} }
} }
func (git gitInput) Compile(_ *State) (*compiler.Value, error) { func (git gitInput) Compile(_ string, _ *State) (*compiler.Value, error) {
ref := "HEAD" ref := "HEAD"
if git.Ref != "" { if git.Ref != "" {
ref = git.Ref ref = git.Ref
@ -148,7 +148,7 @@ type dockerInput struct {
Ref string `json:"ref,omitempty"` Ref string `json:"ref,omitempty"`
} }
func (i dockerInput) Compile(_ *State) (*compiler.Value, error) { func (i dockerInput) Compile(_ string, _ *State) (*compiler.Value, error) {
panic("NOT IMPLEMENTED") panic("NOT IMPLEMENTED")
} }
@ -162,7 +162,7 @@ func TextInput(data string) Input {
type textInput string type textInput string
func (i textInput) Compile(_ *State) (*compiler.Value, error) { func (i textInput) Compile(_ string, _ *State) (*compiler.Value, error) {
return compiler.Compile("", fmt.Sprintf("%q", i)) return compiler.Compile("", fmt.Sprintf("%q", i))
} }
@ -176,8 +176,12 @@ func SecretInput(data string) Input {
type secretInput string type secretInput string
func (i secretInput) Compile(_ *State) (*compiler.Value, error) { func (i secretInput) Compile(key string, _ *State) (*compiler.Value, error) {
return compiler.Compile("", fmt.Sprintf("%q", i)) return compiler.Compile("", fmt.Sprintf(`{id:%q}`, "secret="+key))
}
func (i secretInput) PlainText() string {
return string(i)
} }
// An input value encoded as JSON // An input value encoded as JSON
@ -190,7 +194,7 @@ func JSONInput(data string) Input {
type jsonInput string type jsonInput string
func (i jsonInput) Compile(_ *State) (*compiler.Value, error) { func (i jsonInput) Compile(_ string, _ *State) (*compiler.Value, error) {
return compiler.DecodeJSON("", []byte(i)) return compiler.DecodeJSON("", []byte(i))
} }
@ -204,7 +208,7 @@ func YAMLInput(data string) Input {
type yamlInput string type yamlInput string
func (i yamlInput) Compile(_ *State) (*compiler.Value, error) { func (i yamlInput) Compile(_ string, _ *State) (*compiler.Value, error) {
return compiler.DecodeYAML("", []byte(i)) return compiler.DecodeYAML("", []byte(i))
} }
@ -220,7 +224,7 @@ type fileInput struct {
Path string `json:"data,omitempty"` Path string `json:"data,omitempty"`
} }
func (i fileInput) Compile(_ *State) (*compiler.Value, error) { func (i fileInput) Compile(_ string, _ *State) (*compiler.Value, error) {
data, err := ioutil.ReadFile(i.Path) data, err := ioutil.ReadFile(i.Path)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -18,6 +18,7 @@ import (
// Re-usable aws-cli component // Re-usable aws-cli component
#CLI: { #CLI: {
config: #Config
package: [string]: string | bool package: [string]: string | bool
#up: [ #up: [
@ -30,86 +31,26 @@ import (
"package": "aws-cli": "=~1.18" "package": "aws-cli": "=~1.18"
} }
}, },
op.#Exec & {
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
aws configure set aws_access_key_id "$(cat /run/secrets/access_key)"
aws configure set aws_secret_access_key "$(cat /run/secrets/secret_key)"
aws configure set default.region "$AWS_DEFAULT_REGION"
aws configure set default.cli_pager ""
aws configure set default.output "json"
"""#,
]
mount: "/run/secrets/access_key": secret: config.accessKey
mount: "/run/secrets/secret_key": secret: config.secretKey
env: AWS_DEFAULT_REGION: config.region
},
] ]
} }
// Helper for writing scripts based on AWS CLI
#Script: {
// AWS code
config: #Config
// Script code (bash)
code: string
// Extra pkgs to install
package: [string]: string | bool
// Files to mount
files: [string]: string
// Env variables
env: [string]: string
// Export file
export: string
// Always execute the script?
always?: bool
// Directory
dir?: dagger.#Artifact
out: {
string
#up: [
op.#Load & {
from: #CLI & {
"package": package
}
},
op.#Mkdir & {
path: "/inputs"
},
for k, v in files {
op.#WriteFile & {
dest: k
content: v
}
},
op.#WriteFile & {
dest: "/entrypoint.sh"
content: code
},
op.#Exec & {
if always != _|_ {
"always": always
}
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"/entrypoint.sh",
]
"env": env
"env": {
AWS_ACCESS_KEY_ID: config.accessKey
AWS_SECRET_ACCESS_KEY: config.secretKey
AWS_DEFAULT_REGION: config.region
AWS_REGION: config.region
AWS_DEFAULT_OUTPUT: "json"
AWS_PAGER: ""
}
if dir != _|_ {
mount: "/inputs/source": from: dir
}
},
op.#Export & {
source: export
format: "string"
},
]
}
}

View File

@ -2,6 +2,7 @@ package ecr
import ( import (
"dagger.io/dagger" "dagger.io/dagger"
"dagger.io/dagger/op"
"dagger.io/aws" "dagger.io/aws"
) )
@ -15,14 +16,37 @@ import (
// ECR credentials // ECR credentials
username: "AWS" username: "AWS"
secret: out @dagger(output) secret: {
@dagger(output)
string
aws.#Script & { #up: [
always: true op.#Load & {
"config": config from: aws.#CLI & {
export: "/out" "config": config
code: """ }
aws ecr get-login-password > /out },
"""
op.#Exec & {
always: true
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
aws ecr get-login-password > /out
"""#,
]
},
op.#Export & {
source: "/out"
format: "string"
},
]
} }
} }

View File

@ -18,12 +18,14 @@ import (
// kubeconfig is the generated kube configuration file // kubeconfig is the generated kube configuration file
kubeconfig: { kubeconfig: {
// FIXME There is a problem with dagger.#Secret type @dagger(output)
string string
#up: [ #up: [
op.#Load & { op.#Load & {
from: aws.#CLI from: aws.#CLI & {
"config": config
}
}, },
op.#WriteFile & { op.#WriteFile & {
@ -42,15 +44,8 @@ import (
"/entrypoint.sh", "/entrypoint.sh",
] ]
env: { env: {
AWS_CONFIG_FILE: "/cache/aws/config" EKS_CLUSTER: clusterName
AWS_ACCESS_KEY_ID: config.accessKey KUBECTL_VERSION: version
AWS_SECRET_ACCESS_KEY: config.secretKey
AWS_DEFAULT_REGION: config.region
AWS_REGION: config.region
AWS_DEFAULT_OUTPUT: "json"
AWS_PAGER: ""
EKS_CLUSTER: clusterName
KUBECTL_VERSION: version
} }
mount: { mount: {
"/cache/aws": "cache" "/cache/aws": "cache"
@ -62,5 +57,5 @@ import (
format: "string" format: "string"
}, },
] ]
} @dagger(output) }
} }

View File

@ -18,54 +18,65 @@ import (
// exported priority // exported priority
priority: out @dagger(output) priority: out @dagger(output)
out: string out: {
string
aws.#Script & { #up: [
always: true op.#Load & {
from: aws.#CLI & {
"config": config
}
},
files: { op.#Exec & {
"/inputs/listenerArn": listenerArn args: [
if vhost != _|_ { "/bin/bash",
"/inputs/vhost": vhost "--noprofile",
} "--norc",
} "-eo",
"pipefail",
#"""
if [ -s "$VHOST" ]; then
# We passed a vhost as input, try to recycle priority from previously allocated vhost
priority=$(aws elbv2 describe-rules \
--listener-arn "$LISTENER_ARN" | \
jq -r --arg vhost "$VHOST" '.Rules[] | select(.Conditions[].HostHeaderConfig.Values[] == $VHOST) | .Priority')
export: "/priority" if [ -n "${priority}" ]; then
echo -n "${priority}" > /priority
exit 0
fi
fi
//FIXME: The code below can end up not finding an available prio # Grab a priority random from 1-50k and check if available, retry 10 times if none available
// Better to exclude the existing allocated priorities from the random sequence priority=0
code: #""" for i in {1..10}
if [ -s /inputs/vhost ]; then do
# We passed a vhost as input, try to recycle priority from previously allocated vhost p=$(shuf -i 1-50000 -n 1)
vhost="$(cat /inputs/vhost)" # Find the next priority available that we can allocate
aws elbv2 describe-rules \
--listener-arn "$LISTENER_ARN" \
| jq -e "select(.Rules[].Priority == \"${p}\") | true" && continue
priority="${p}"
break
done
if [ "${priority}" -lt 1 ]; then
echo "Error: cannot determine a Rule priority"
exit 1
fi
echo -n "${priority}" > /priority
"""#,
]
env: {
LISTENER_ARN: listenerArn
VHOST: vhost
}
},
priority=$(aws elbv2 describe-rules \ op.#Export & {
--listener-arn "$(cat /inputs/listenerArn)" | \ source: "/db_created"
jq -r --arg vhost "$vhost" '.Rules[] | select(.Conditions[].HostHeaderConfig.Values[] == $vhost) | .Priority') format: "string"
},
if [ -n "${priority}" ]; then ]
echo -n "${priority}" > /priority
exit 0
fi
fi
# Grab a priority random from 1-50k and check if available, retry 10 times if none available
priority=0
for i in {1..10}
do
p=$(shuf -i 1-50000 -n 1)
# Find the next priority available that we can allocate
aws elbv2 describe-rules \
--listener-arn "$(cat /inputs/listenerArn)" \
| jq -e "select(.Rules[].Priority == \"${p}\") | true" && continue
priority="${p}"
break
done
if [ "${priority}" -lt 1 ]; then
echo "Error: cannot determine a Rule priority"
exit 1
fi
echo -n "${priority}" > /priority
"""#
} }
} }

View File

@ -22,45 +22,60 @@ import (
dbType: "mysql" | "postgres" @dagger(input) dbType: "mysql" | "postgres" @dagger(input)
// Name of the DB created // Name of the DB created
out: string @dagger(output) out: {
@dagger(output)
string
aws.#Script & { #up: [
"config": config op.#Load & {
from: aws.#CLI & {
"config": config
}
},
files: { op.#Exec & {
"/inputs/name": name args: [
"/inputs/db_arn": dbArn "/bin/bash",
"/inputs/secret_arn": secretArn "--noprofile",
"/inputs/db_type": dbType "--norc",
} "-eo",
"pipefail",
#"""
echo "dbType: $DB_TYPE"
export: "/db_created" sql="CREATE DATABASE \`"$NAME" \`"
if [ "$DB_TYPE" = postgres ]; then
sql="CREATE DATABASE \""$NAME"\""
fi
code: #""" echo "$NAME" >> /db_created
set +o pipefail
dbType="$(cat /inputs/db_type)" aws rds-data execute-statement \
echo "dbType: $dbType" --resource-arn "$DB_ARN" \
--secret-arn "$SECRET_ARN" \
--sql "$sql" \
--database "$DB_TYPE" \
--no-include-result-metadata \
|& tee /tmp/out
exit_code=${PIPESTATUS[0]}
if [ $exit_code -ne 0 ]; then
grep -q "database exists\|already exists" /tmp/out || exit $exit_code
fi
"""#,
]
env: {
NAME: name
DB_ARN: dbArn
SECRET_ARN: secretArn
DB_TYPE: dbType
}
},
sql="CREATE DATABASE \`$(cat /inputs/name)\`" op.#Export & {
if [ "$dbType" = postgres ]; then source: "/db_created"
sql="CREATE DATABASE \"$(cat /inputs/name)\"" format: "string"
fi },
]
cp /inputs/name /db_created
aws rds-data execute-statement \
--resource-arn "$(cat /inputs/db_arn)" \
--secret-arn "$(cat /inputs/secret_arn)" \
--sql "$sql" \
--database "$dbType" \
--no-include-result-metadata \
|& tee /tmp/out
exit_code=${PIPESTATUS[0]}
if [ $exit_code -ne 0 ]; then
grep -q "database exists\|already exists" /tmp/out || exit $exit_code
fi
"""#
} }
} }
@ -69,89 +84,104 @@ import (
config: aws.#Config config: aws.#Config
// Username // Username
username: dagger.#Secret username: dagger.#Secret @dagger(input)
// Password // Password
password: dagger.#Secret password: dagger.#Secret @dagger(input)
// ARN of the database instance // ARN of the database instance
dbArn: string dbArn: string @dagger(input)
// ARN of the database secret (for connecting via rds api) // ARN of the database secret (for connecting via rds api)
secretArn: string secretArn: string @dagger(input)
grantDatabase: string | *"" grantDatabase: string | *"" @dagger(input)
dbType: "mysql" | "postgres" dbType: "mysql" | "postgres" @dagger(input)
// Outputed username // Outputed username
out: string out: {
@dagger(output)
string
aws.#Script & { #up: [
"config": config op.#Load & {
from: aws.#CLI & {
"config": config
}
},
files: { op.#Exec & {
"/inputs/username": username args: [
"/inputs/password": password "/bin/bash",
"/inputs/db_arn": dbArn "--noprofile",
"/inputs/secret_arn": secretArn "--norc",
"/inputs/grant_database": grantDatabase "-eo",
"/inputs/db_type": dbType "pipefail",
} #"""
echo "dbType: $DB_TYPE"
sql="CREATE USER '"$USERNAME"'@'%' IDENTIFIED BY '"$PASSWORD"'"
if [ "$DB_TYPE" = postgres ]; then
sql="CREATE USER \""$USERNAME"\" WITH PASSWORD '"$PASSWORD"'"
fi
echo "$USERNAME" >> /username
aws rds-data execute-statement \
--resource-arn "$DB_ARN" \
--secret-arn "$SECRET_ARN" \
--sql "$sql" \
--database "$DB_TYPE" \
--no-include-result-metadata \
|& tee tmp/out
exit_code=${PIPESTATUS[0]}
if [ $exit_code -ne 0 ]; then
grep -q "Operation CREATE USER failed for\|ERROR" tmp/out || exit $exit_code
fi
sql="SET PASSWORD FOR '"$USERNAME"'@'%' = PASSWORD('"$PASSWORD"')"
if [ "$DB_TYPE" = postgres ]; then
sql="ALTER ROLE \""$USERNAME"\" WITH PASSWORD '"$PASSWORD"'"
fi
aws rds-data execute-statement \
--resource-arn "$DB_ARN" \
--secret-arn "$SECRET_ARN" \
--sql "$sql" \
--database "$DB_TYPE" \
--no-include-result-metadata
sql="GRANT ALL ON \`"$GRAND_DATABASE"\`.* to '"$USERNAME"'@'%'"
if [ "$DB_TYPE" = postgres ]; then
sql="GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \""$USERNAME"\"; GRANT ALL PRIVILEGES ON DATABASE \""$GRAND_DATABASE"\" to \""$USERNAME"\"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \""$USERNAME"\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO \""$USERNAME"\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO \""$USERNAME"\"; GRANT USAGE ON SCHEMA public TO \""$USERNAME"\";"
fi
if [ -s "$GRAND_DATABASE ]; then
aws rds-data execute-statement \
--resource-arn "$DB_ARN" \
--secret-arn "$SECRET_ARN" \
--sql "$sql" \
--database "$DB_TYPE" \
--no-include-result-metadata
fi
"""#,
]
env: {
USERNAME: unsername
PASSWORD: password
DB_ARN: dbArn
SECRET_ARN: secretArn
GRAND_DATABASE: grandDatabase
DB_TYPE: dbType
}
},
export: "/username" op.#Export & {
source: "/username"
code: #""" format: "string"
set +o pipefail },
]
dbType="$(cat /inputs/db_type)"
echo "dbType: $dbType"
sql="CREATE USER '$(cat /inputs/username)'@'%' IDENTIFIED BY '$(cat /inputs/password)'"
if [ "$dbType" = postgres ]; then
sql="CREATE USER \"$(cat /inputs/username)\" WITH PASSWORD '$(cat /inputs/password)'"
fi
cp /inputs/username /username
aws rds-data execute-statement \
--resource-arn "$(cat /inputs/db_arn)" \
--secret-arn "$(cat /inputs/secret_arn)" \
--sql "$sql" \
--database "$dbType" \
--no-include-result-metadata \
|& tee tmp/out
exit_code=${PIPESTATUS[0]}
if [ $exit_code -ne 0 ]; then
grep -q "Operation CREATE USER failed for\|ERROR" tmp/out || exit $exit_code
fi
sql="SET PASSWORD FOR '$(cat /inputs/username)'@'%' = PASSWORD('$(cat /inputs/password)')"
if [ "$dbType" = postgres ]; then
sql="ALTER ROLE \"$(cat /inputs/username)\" WITH PASSWORD '$(cat /inputs/password)'"
fi
aws rds-data execute-statement \
--resource-arn "$(cat /inputs/db_arn)" \
--secret-arn "$(cat /inputs/secret_arn)" \
--sql "$sql" \
--database "$dbType" \
--no-include-result-metadata
sql="GRANT ALL ON \`$(cat /inputs/grant_database)\`.* to '$(cat /inputs/username)'@'%'"
if [ "$dbType" = postgres ]; then
sql="GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"$(cat /inputs/username)\"; GRANT ALL PRIVILEGES ON DATABASE \"$(cat /inputs/grant_database)\" to \"$(cat /inputs/username)\"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \"$(cat /inputs/username)\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO \"$(cat /inputs/username)\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO \"$(cat /inputs/username)\"; GRANT USAGE ON SCHEMA public TO \"$(cat /inputs/username)\";"
fi
if [ -s /inputs/grant_database ]; then
aws rds-data execute-statement \
--resource-arn "$(cat /inputs/db_arn)" \
--secret-arn "$(cat /inputs/secret_arn)" \
--sql "$sql" \
--database "$dbType" \
--no-include-result-metadata
fi
"""#
} }
} }
@ -160,35 +190,51 @@ import (
config: aws.#Config config: aws.#Config
// ARN of the database instance // ARN of the database instance
dbArn: string dbArn: string @dagger(input)
// DB hostname // DB hostname
hostname: info.hostname hostname: info.hostname @dagger(output)
// DB port // DB port
port: info.port port: info.port @dagger(output)
info: { info: {
hostname: string hostname: string
port: int port: int
} }
info: json.Unmarshal(out) info: json.Unmarshal(out) @dagger(output)
out: string out: {
string
aws.#Script & { #up: [
"config": config op.#Load & {
from: aws.#CLI & {
"config": config
}
},
files: "/inputs/db_arn": dbArn op.#Exec & {
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
#"""
data=$(aws rds describe-db-clusters --filters "Name=db-cluster-id,Values=$DB_URN" )
echo "$data" | jq -r '.DBClusters[].Endpoint' > /tmp/out
echo "$data" | jq -r '.DBClusters[].Port' >> /tmp/out
cat /tmp/out | jq -sR 'split("\n") | {hostname: .[0], port: (.[1] | tonumber)}' > /out
"""#,
]
env: DB_ARN: dbArn
},
export: "/out" op.#Export & {
source: "/out"
code: #""" format: "json"
db_arn="$(cat /inputs/db_arn)" },
data=$(aws rds describe-db-clusters --filters "Name=db-cluster-id,Values=$db_arn" ) ]
echo "$data" | jq -r '.DBClusters[].Endpoint' > /tmp/out
echo "$data" | jq -r '.DBClusters[].Port' >> /tmp/out
cat /tmp/out | jq -sR 'split("\n") | {hostname: .[0], port: (.[1] | tonumber)}' > /out
"""#
} }
} }

View File

@ -2,6 +2,7 @@ package s3
import ( import (
"dagger.io/dagger" "dagger.io/dagger"
"dagger.io/dagger/op"
"dagger.io/aws" "dagger.io/aws"
) )
@ -23,46 +24,69 @@ import (
// Object content type // Object content type
contentType: string | *"" @dagger(input) contentType: string | *"" @dagger(input)
// URL of the uploaded S3 object
url: out @dagger(output)
// Always write the object to S3 // Always write the object to S3
always?: bool @dagger(input) always?: bool @dagger(input)
out: string // URL of the uploaded S3 object
aws.#Script & { url: {
if always != _|_ { @dagger(output)
"always": always string
}
files: { #up: [
op.#Load & {
from: aws.#CLI & {
"config": config
}
},
if sourceInline != _|_ { if sourceInline != _|_ {
"/inputs/source": sourceInline op.#WriteFile & {
} dest: "/source"
"/inputs/target": target content: sourceInline
if contentType != "" { }
"/inputs/content_type": contentType },
}
}
export: "/url" op.#Exec & {
if always != _|_ {
"always": always
}
env: {
TARGET: target
CONTENT_TYPE: contentType
}
code: #""" if sourceInline == _|_ {
opts="" mount: "/source": from: source
op=cp }
if [ -d /inputs/source ]; then
op=sync
fi
if [ -f /inputs/content_type ]; then
opts="--content-type $(cat /inputs/content_type)"
fi
aws s3 $op $opts /inputs/source "$(cat /inputs/target)"
cat /inputs/target \
| sed -E 's=^s3://([^/]*)/=https://\1.s3.amazonaws.com/=' \
> /url
"""#
if sourceInline == _|_ { args: [
dir: source "/bin/bash",
} "--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
opts=""
op=cp
if [ -d /source ]; then
op=sync
fi
if [ -n "$CONTENT_TYPE" ]; then
opts="--content-type $CONTENT_TYPE"
fi
aws s3 $op $opts /source "$TARGET"
echo "$TARGET" \
| sed -E 's=^s3://([^/]*)/=https://\1.s3.amazonaws.com/=' \
> /url
"""#,
]
},
op.#Export & {
source: "/url"
format: "string"
},
]
} }
} }

View File

@ -15,9 +15,8 @@ import (
} }
// Secret value // Secret value
// FIXME: currently aliased as a string to mark secrets
// this requires proper support.
#Secret: { #Secret: {
@dagger(secret) @dagger(secret)
string | bytes
id: string
} }

View File

@ -57,7 +57,7 @@ package op
// `true` means also ignoring the mount cache volumes // `true` means also ignoring the mount cache volumes
always?: true | *false always?: true | *false
dir: string | *"/" dir: string | *"/"
mount: [string]: "tmpfs" | "cache" | {from: _, path: string | *"/"} mount: [string]: "tmpfs" | "cache" | {from: _, path: string | *"/"} | {secret: _}
// Map of hostnames to ip // Map of hostnames to ip
hosts?: [string]: string hosts?: [string]: string
// User to exec with (if left empty, will default to the set user in the image) // User to exec with (if left empty, will default to the set user in the image)

View File

@ -32,14 +32,9 @@ import (
] ]
}, },
// Setup auth
op.#WriteFile & {
dest: "/service_key"
content: config.serviceKey
},
op.#Exec & { op.#Exec & {
args: ["gcloud", "-q", "auth", "activate-service-account", "--key-file=/service_key"] args: ["gcloud", "-q", "auth", "activate-service-account", "--key-file=/service_key"]
mount: "/service_key": secret: config.serviceKey
}, },
op.#Exec & { op.#Exec & {

View File

@ -80,10 +80,10 @@ import (
if customDomain != _|_ { if customDomain != _|_ {
NETLIFY_DOMAIN: customDomain NETLIFY_DOMAIN: customDomain
} }
NETLIFY_ACCOUNT: account.name NETLIFY_ACCOUNT: account.name
NETLIFY_AUTH_TOKEN: account.token
} }
dir: "/src" dir: "/src"
mount: "/src": from: contents mount: "/src": from: contents
mount: "/run/secrets/token": secret: account.token
} }
} }

View File

@ -1,6 +1,8 @@
package netlify package netlify
#Site: ctr: command: #""" #Site: ctr: command: #"""
export NETLIFY_AUTH_TOKEN="$(cat /run/secrets/token)"
create_site() { create_site() {
url="https://api.netlify.com/api/v1/${NETLIFY_ACCOUNT:-}/sites" url="https://api.netlify.com/api/v1/${NETLIFY_ACCOUNT:-}/sites"

View File

@ -52,6 +52,8 @@ import (
mount: [string]: { mount: [string]: {
from: dagger.#Artifact from: dagger.#Artifact
// FIXME: support source path // FIXME: support source path
} | {
secret: dagger.#Secret
} }
// Mount persistent cache directories // Mount persistent cache directories
@ -94,10 +96,9 @@ import (
// Execute setup commands, without volumes // Execute setup commands, without volumes
for cmd in setup { for cmd in setup {
op.#Exec & { op.#Exec & {
args: [shell.path] + shell.args + [cmd] args: [shell.path] + shell.args + [cmd]
"env": env "env": env
"dir": dir "dir": dir
"always": always
} }
}, },
// Execute main command with volumes // Execute main command with volumes
@ -109,7 +110,7 @@ import (
"always": always "always": always
"mount": { "mount": {
for dest, o in mount { for dest, o in mount {
"\(dest)": from: o.from "\(dest)": o
// FIXME: support source path // FIXME: support source path
} }
for dest in cache { for dest in cache {

View File

@ -67,6 +67,33 @@ setup() {
assert_line '{"in":"foobar","test":"received: foobar"}' assert_line '{"in":"foobar","test":"received: foobar"}'
} }
@test "compute: secrets" {
# secrets used as environment variables must fail
run "$DAGGER" compute "$TESTDIR"/compute/secrets/invalid/env
assert_failure
assert_line --partial "conflicting values"
# strings passed as secrets must fail
run "$DAGGER" compute "$TESTDIR"/compute/secrets/invalid/string
assert_failure
# Setting a text input for a secret value should fail
run "$DAGGER" compute --input-string 'mySecret=SecretValue' "$TESTDIR"/compute/secrets/simple
assert_failure
# Now test with an actual secret and make sure it works
"$DAGGER" init
dagger_new_with_plan secrets "$TESTDIR"/compute/secrets/simple
"$DAGGER" input secret mySecret SecretValue
run "$DAGGER" up
assert_success
# Make sure the secret doesn't show in dagger query
run "$DAGGER" query mySecret.id -f text
assert_success
assert_output "secret=mySecret"
}
@test ".daggerignore" { @test ".daggerignore" {
"$DAGGER" compute --input-dir TestData="$TESTDIR"/compute/ignore/testdata "$TESTDIR"/compute/ignore "$DAGGER" compute --input-dir TestData="$TESTDIR"/compute/ignore/testdata "$TESTDIR"/compute/ignore
} }

View File

@ -0,0 +1,21 @@
package testing
import (
"dagger.io/dagger"
"dagger.io/dagger/op"
"dagger.io/alpine"
)
mySecret: dagger.#Secret
TestSecrets: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "=~5.1"
}
},
op.#Exec & {
env: foo: mySecret
},
]

View File

@ -0,0 +1,21 @@
package testing
import (
"dagger.io/dagger/op"
"dagger.io/alpine"
)
mySecret: dagger.#Secret
TestString: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "=~5.1"
}
},
op.#Exec & {
mount: "/secret": secret: mySecret
args: ["true"]
},
]

View File

@ -0,0 +1,34 @@
package testing
import (
"dagger.io/dagger"
"dagger.io/dagger/op"
"dagger.io/alpine"
)
mySecret: dagger.#Secret
TestSecrets: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "=~5.1"
}
},
op.#Exec & {
mount: "/secret": secret: mySecret
env: PLAIN: mySecret.id
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
test "$(cat /secret)" = "SecretValue"
test "$PLAIN" != "SecretValue"
"""#,
]
},
]

View File

@ -5,15 +5,14 @@ setup() {
} }
@test "example: react" { @test "example: react" {
skip_unless_secrets_available "$TESTDIR"/examples/react/inputs.yaml cp -R "$TESTDIR"/examples/react/.dagger "$DAGGER_WORKSPACE"/.dagger
mkdir "$DAGGER_WORKSPACE"/.dagger/env/default/plan
cp -R "$TESTDIR"/../examples/react/*.cue "$DAGGER_WORKSPACE"/.dagger/env/default/plan
"$DAGGER" init "$DAGGER" up
dagger_new_with_plan react "$TESTDIR"/../examples/react
sops -d "$TESTDIR"/examples/react/inputs.yaml | "$DAGGER" -e "react" input yaml "" -f -
"$DAGGER" up -e "react"
# curl the URL we just deployed to check if it worked # curl the URL we just deployed to check if it worked
deployUrl=$("$DAGGER" query -l error -f text -e "react" www.deployUrl) deployUrl=$("$DAGGER" query -l error -f text www.deployUrl)
run curl -sS "$deployUrl" run curl -sS "$deployUrl"
assert_success assert_success
assert_output --partial "Todo App" assert_output --partial "Todo App"

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,26 @@
name: default
inputs:
www.account.name:
text: blocklayer
www.account.token:
secret: ENC[AES256_GCM,data:AGeCt/UJzWJ4UnzS/+t21GYz5wXPUoplYXTi1USXdi72wZemhzZncR2a+A==,iv:07DgGFL0oKgQsSZnp9s/Zz+6rdLShtHfStJZ9tHpsI4=,tag:jkY6TMrf7DaJMAc8/kJcAw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBudkl4d2czaHZkSGt0SnVm
dm8xRTdaRE1WenpOczYxRFdMcDRkWDNmL1VzCjRHeWt3dnBITjlSNDZteWJhRmha
NWsrTThTZCt2eDJkRjgyOTFJeHdBMzgKLS0tIE9jOTFWMTRQei9iUkcvZDFrbmxn
ZnFaRWtEM241cDVCTStnK25BcDYyWlUKT2U8IFC21xMigjaTHHgkdUxIXKshxTmg
Q8254/qEWk+mJfsGxPf54d1RtqNqDX17kK/LeooSYAz7aqBjVLfG6w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-28T20:06:11Z"
mac: ENC[AES256_GCM,data:GnbN0nu7ZFZHtyXxZIQ+p1CuYm3TPR+zAZa7FcsIvuQgase1DEMySIV2MJIwhhj/6PMEngs4HSIIo/61qFpFI47CELxgwmfUPadtJVG9Z3o9HterMFrHHXQL+ULxXjP7jDeXhcsEDh1GN+yroc7mFy3SM9Typ3FVzyIq/Lqek5U=,iv:68S92VPpLtj+rwTapqx6IyHJQFmiXpHOQoyxpvH7MD4=,tag:C3Jj9mkeTNCe8EkFAwRYAg==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -1,34 +0,0 @@
www:
account:
name: ENC[AES256_GCM,data:EsPTWeiDCrVeUQ==,iv:9/tZQOrrjQejsK6NFcgQO9HaAnjIUv1Qc+S0slds+4o=,tag:n3NYautI94ilmEWG9UeFzA==,type:str]
token: ENC[AES256_GCM,data:Jx7oVJXcMX3hBmC6Kld7jxOOH/3CGSAzC7rRhHgs25iLFZG+F3iN5fYYVA==,iv:9SVNNv5CTM0AZns0x7x5bSI6jW93jSh8Xt21hXN1g28=,tag:QKBf7OsKs1TxvMA4gdA53Q==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2021-04-09T01:47:48Z'
mac: ENC[AES256_GCM,data:UqOr8wGUwf6iVnurG/dvpiZVN0k9NrLTaB5CQVn+QTRQybgYuLZLTJuTFNlAqFGvNO07OoGkDx/Vmhw9F6nJS0qUcHC5iWg+Bxaa7anHwer7fkA/xTjKpqJnE6iveq+hzumDgeFbGL7+EJvbyxtJioF/LnWa5gnduBVacizjbKc=,iv:x4ulAfd2R0BdkGF4zkMn+wX+Y8wF3jEeFOu3+5t+wz4=,tag:e5uOip0iAt9xJa6RJGukCA==,type:str]
pgp:
- created_at: '2021-03-18T22:02:51Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAzqVY590vudzAQ/5ARrCGVOpwmCdsKV4MHwwGvmQCOhfidOqftWUXV5j3s08
LFbwZcnTaHDNobgebmgS9WVwiR2GA955Fopz89Tp6MDVNkgQKK6rbJjpBCBrNTR9
ko0/VLklrtW00PEWih23NOCinoFXk/yVlDaxDiyTzIdaYr5yY8nBsde7Kx7v1VqP
Hniu65318B8EGGpPTbB8vG+9nAiZganCJmrzSNUo41jpmhPhRhAPQBVAWoBbJ4i1
2MOtd46KWGsV+Y6+vqTwnJ1BuCOW1QzxaTp2AHlgYnApidqK8RFTOKONmfF0jgkk
bKi5JIK2nObytHopuUj9wU0XkMqbHYYD9XbBXqGeMFmftvyGUqOzPZSTLYObTQbS
/wKWjCnwHfRRWq9+z56K27EBY9ksgGEUhDA+IdhZPKfXBrW4N9u4YZHfMCJk1mPQ
oAQzWAResWvyzuI+q3OlTmax95COog8kv1Xe2Mf/XNGLvkyvp9de8jtPkK23/CON
0+7tH/p0UDrJZFNRQn65P18S0rgc1u2GOE5allD4th8TGNx1zk8GWNgc+jBUasnc
teVToBpDejC4JtF2NcDm2zyXdhjXF9msGJWcofgwJgPciBy/j4D+X6+3MUvyjvv+
DU4DmIq2a3sTVBQ0xdsAsF2phkjCUeFQY4LdcSbEUsvDuiTpoNq5yhY6ESMiny/S
XgHByC8CVHfz/3XosgBo6lOTCwwP8yCLe+vJwEt3EiOZiNVQ8WUogIlq5hU91oTQ
B5LTVCm2rJNb5zQzOd7/aF0t0h46xaZHm2WS0jsEwEWZM86OUPk8sAmFHRcVQ+s=
=qLN2
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted
version: 3.6.1

View File

@ -12,6 +12,9 @@ common_setup() {
DAGGER_WORKSPACE="$(mktemp -d -t dagger-workspace-XXXXXX)" DAGGER_WORKSPACE="$(mktemp -d -t dagger-workspace-XXXXXX)"
export DAGGER_WORKSPACE export DAGGER_WORKSPACE
SOPS_AGE_KEY_FILE=~/.dagger/keys.txt
export SOPS_AGE_KEY_FILE
} }
dagger_new_with_plan() { dagger_new_with_plan() {

View File

@ -1,34 +1,23 @@
registry: registry:
username: ENC[AES256_GCM,data:8AH6p9WHidanCA==,iv:ezThCQJv+bVBf8SdfSa2HFoP+eu6IZMPl5xvMOGDcps=,tag:mzR7xTKeQNDvkyd2Dm3AKw==,type:str] username: ENC[AES256_GCM,data:Yuv+E9dhGZnCxw==,iv:ezThCQJv+bVBf8SdfSa2HFoP+eu6IZMPl5xvMOGDcps=,tag:8+EeJfySzwMczqrzIEDy+w==,type:str]
secret: ENC[AES256_GCM,data:GtuaBAhFBw2JFaeuOm6mUr3m1j5fvCJjcWAzjsdU2xASFxwO,iv:YAXcRzBoemmef5PBdAOBa5acNPo4BoKH7Ngud/CWYfA=,tag:MCCUCOSutjRCI92raYrxdg==,type:str] secret: ENC[AES256_GCM,data:OcxwHjWcTdtyKRb7whgG/fzmIG/bpQoSlUVIIhyeEX31lGWh,iv:YAXcRzBoemmef5PBdAOBa5acNPo4BoKH7Ngud/CWYfA=,tag:M1M1hsqKP0TyQbkU5c6oGg==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age:
lastmodified: "2021-04-27T00:59:33Z" - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
mac: ENC[AES256_GCM,data:qk+oo4m5OpfuQ+R3pZUuvn+gqAk15OAJzOULrlYqt1FIDRk/Q5ah5QpIbVxeP1EDVyuY/V/E0ZngRlSV7Dyx6Cp/moMd8AFBHNgnTB+Lq+NmZ9HR1QMOxpbMpJmUGn7MqQ1Ys4wy0p2q2Y2+TuUpKwmRGJbGVYEVmqvV5OT3jhc=,iv:QsUFa2GVzy6iqqLXRz8HascQZPIIzKBhxHdlabov02k=,tag:7lk63FeXsOlTCgfmWd7zrg==,type:str]
pgp:
- created_at: "2021-03-18T22:59:59Z"
enc: | enc: |
-----BEGIN PGP MESSAGE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOaE5NYkdtR0FiOWZTcW54
hQIMAzqVY590vudzAQ//etnfnpfCo9rAkctR+Fwg/7VdVL3Rov+6gnyjUnoN1BS1 UzRTL3lwQ3owV0QyWmYzVmQ1K0swa2xZK0RnClZSblRIQUxpUWNUdGJBMngwRlFT
8jnBF/86AZ7uK89dTcTZCsK1hKPxeYg1kJTKpA+zfDORupzTWcMrRyjwNk5wQ2Vg RXI1aHJMUVVySVF2dzBLN1djZitSWlEKLS0tIGd6RWttckdQTVV1Qi9uWUEvQitR
N1adUwFsBQpk8WptpsU/ro6+3yH+Nn35begs6hP2fH/EQ9XOxw5gY0kp0AFjGaKJ ODEwdXlXSy8veWZkNUpNbWszMVE3M0EKSiQ0AVvySOUHg6RZkcbmpLTHSlnT2zw7
tRZVrr3f2hpLESo6LILRO97UXZiGcwTn5onslECL92260cU1nqEQp+ESK7XrdYIG Em+pRLYs7GXyilGvSwlRw5O+SrNNQU8Tr8/Yumif2Mks5r3TatDqdA==
99oM3eXEraKw4WuQDaDE6U135aUl6vIJWD1JZzyr3RW3+5O9pn5rpN3Wc0TbDR6+ -----END AGE ENCRYPTED FILE-----
9Fs/TjuA1h5eJzbt+lkA74BtxPOBv9O7HJnWJpXjiG0VUGHdFXoq5Tr5Ol68RQxa lastmodified: "2021-05-28T20:47:36Z"
BWe7IfTO6FHN0xOl1dY7cn5jtf+xlFjL86s9OkrJUFa9lbQx8L/QPCeA2Xiu4tpW mac: ENC[AES256_GCM,data:tSOZ6GWrpwPkwCYdtN9/Ym9OXGDzLfXaTATBodaLVjxsVtjaFSxjN15gcjtcxU9KNiOo77fJuEgHgQTQmzHrjSBkvX0zgGoNGU1KCQ3XqRMzfjm1yBU7sWb7lCwjAUqzhERRwe9Vja9GkDSgT+B+CUIRDyqQa1jXg0HlQldhEr0=,iv:ZioCDF8NueNw9miTWxhYWvn1cDw9wUxzMIlp9b2UEgE=,tag:CM4mbhrYW83/ijHNRtIWBw==,type:str]
+wTSel13k8Uv/JSGgLwSohW6N4XTQYdxPkO+a1V08adwFBXaGgqxfg0rNehcS5fp pgp: []
y3TEq84cOlBsaI+rYpnOTPEajtYWfTe8WFf+lBOn1vZ9EiupjZtefGX2MIWPXoaK
kVBgRvzjp4/BY68yRvdi5sZFd2nakl+DOXzouuFbzsOkxL3o9FA9aCVsXtFqqzSG
Hvq4ZJ5ivXf6vQf+s7Tgc4qxW2CQwIPZVkHhQossrWgtkQ4WDAyzfhF0YuhEnpLS
XgGNLr82LMVmempaJd7GfAR2nwGnLUTYny1KoiW/1ie6DPwLZBX/UxPOplaS5wYH
Xd3gV3smg5xZ7/rfvzKTzJ1a5yH6D3xI05UtnUWdqojONcXS9NS+P7RArngJwSs=
=m0OS
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.7.1 version: 3.7.1

View File

@ -8,7 +8,7 @@ import (
registry: { registry: {
username: string username: string
secret: dagger.#Secret secret: string
} }
TestPushContainer: { TestPushContainer: {

View File

@ -21,9 +21,7 @@ setup() {
} }
@test "stdlib: netlify" { @test "stdlib: netlify" {
skip_unless_secrets_available "$TESTDIR"/stdlib/netlify/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/netlify/
"$DAGGER" compute "$TESTDIR"/stdlib/netlify --input-yaml "$TESTDIR"/stdlib/netlify/inputs.yaml
} }
@test "stdlib: kubernetes" { @test "stdlib: kubernetes" {
@ -43,33 +41,23 @@ setup() {
} }
@test "stdlib: aws: s3" { @test "stdlib: aws: s3" {
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/aws/s3
"$DAGGER" compute "$TESTDIR"/stdlib/aws/s3 --input-dir TestDirectory="$TESTDIR"/stdlib/aws/s3/testdata --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
} }
@test "stdlib: aws: eks" { @test "stdlib: aws: eks" {
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/aws/eks
"$DAGGER" compute "$TESTDIR"/stdlib/aws/eks --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
} }
@test "stdlib: aws: ecr" { @test "stdlib: aws: ecr" {
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/aws/ecr
"$DAGGER" compute "$TESTDIR"/stdlib/aws/ecr --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
} }
@test "stdlib: gcp: gke" { @test "stdlib: gcp: gke" {
skip_unless_secrets_available "$TESTDIR"/stdlib/gcp/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/gcp/gke
"$DAGGER" compute "$TESTDIR"/stdlib/gcp/gke --input-yaml "$TESTDIR"/stdlib/gcp/inputs.yaml
} }
@test "stdlib: gcp: gcr" { @test "stdlib: gcp: gcr" {
skip_unless_secrets_available "$TESTDIR"/stdlib/gcp/inputs.yaml "$DAGGER" up -w "$TESTDIR"/stdlib/gcp/gcr
"$DAGGER" compute "$TESTDIR"/stdlib/gcp/gcr --input-yaml "$TESTDIR"/stdlib/gcp/inputs.yaml
} }
@test "stdlib: docker-build" { @test "stdlib: docker-build" {
@ -89,14 +77,14 @@ setup() {
} }
@test "stdlib: terraform" { @test "stdlib: terraform" {
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml skip_unless_secrets_available "$TESTDIR"/stdlib/terraform/s3/inputs.yaml
"$DAGGER" init "$DAGGER" init
dagger_new_with_plan terraform "$TESTDIR"/stdlib/terraform/s3 dagger_new_with_plan terraform "$TESTDIR"/stdlib/terraform/s3
cp -R "$TESTDIR"/stdlib/terraform/s3/testdata "$DAGGER_WORKSPACE"/testdata cp -R "$TESTDIR"/stdlib/terraform/s3/testdata "$DAGGER_WORKSPACE"/testdata
"$DAGGER" -e terraform input dir TestData "$DAGGER_WORKSPACE"/testdata "$DAGGER" -e terraform input dir TestData "$DAGGER_WORKSPACE"/testdata
sops -d "$TESTDIR"/stdlib/aws/inputs.yaml | "$DAGGER" -e "terraform" input yaml "" -f - sops -d "$TESTDIR"/stdlib/terraform/s3/inputs.yaml | "$DAGGER" -e "terraform" input yaml "" -f -
# it must fail because of a missing var # it must fail because of a missing var
run "$DAGGER" up -e terraform run "$DAGGER" up -e terraform

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,26 @@
name: default
inputs:
TestConfig.awsConfig.accessKey:
secret: ENC[AES256_GCM,data:iu6LfQNgGZUVnHVeMRYPrcBtlZk=,iv:U5PLxDKXwJnUDdk1ayFGvvJfWdVqh1PK5ujb20YYPP0=,tag:QyqIJRiR6nE16ZDV0CP7Pw==,type:str]
TestConfig.awsConfig.secretKey:
secret: ENC[AES256_GCM,data:Q/W+KH3NEouGt6C5S+KiC43837soYi2Mjb/z5K8rD9gtaNaBjjkJHg==,iv:8nGEzLXd91rF5YBZ/EdQoMN27yrpc0sgm26DEvIuSHM=,tag:/oyKl/vj5MJAm+jZMOOAuQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKeEk5MS9nVmFoOVNNOHdE
WnZCTXBWbW9LL1NJYndCYjhIM2JsNXNEUmxJCkUya0dlZjZ0dGRIM1pVdzg5eWFH
MVpiaE9PclNudGdUZm5FcytuVDZGTDAKLS0tIEQxWDdteHgzS3JkdmtNTVpxMUh1
aXlvVWJVSGNTSkVyYmpZbi9nUVJZdmMK6csXZ2RMxFw5DB+Hb2TyhyoZT8c2/z7Y
Lc9Pe8gb8aUq5Ha+wCybYvY6JWEM5A9XYJKbE7f4borTfGKS72d6pw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-27T00:53:54Z"
mac: ENC[AES256_GCM,data:ho/e/xUzRdwwe3VRCz9p8UNHgxdhAxkNtWUJLS5fEXBGnw28hjwNBbPYN78bX0k9SQ/5bgvXT2O/Z+zmOSWfrCYD2eojh9mDR4aCV5m/liVh5Dxha65u6zPl9VVcSunYg3wqe9Zl+pMG8BJXvczQS7S5QEGEaWojfaA/o7HM1BE=,iv:o/cVw6GBCCdgIqIZGDzqSCiBHUmrhAoIRcyGS9P83j0=,tag:WSQO0C0lPH2vOzl07rmRGg==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,53 @@
package eks
import (
"dagger.io/aws"
"dagger.io/aws/eks"
"dagger.io/kubernetes"
"dagger.io/dagger/op"
)
TestConfig: awsConfig: aws.#Config & {
region: "us-east-2"
}
TestCluster: eks.#KubeConfig & {
config: TestConfig.awsConfig
clusterName: *"dagger-example-eks-cluster" | string
}
TestEks: {
#GetPods:
"""
kubectl get pods -A
"""
#up: [
op.#Load & {
from: kubernetes.#Kubectl
},
op.#WriteFile & {
dest: "/kubeconfig"
content: TestCluster.kubeconfig
},
op.#WriteFile & {
dest: "/getPods.sh"
content: #GetPods
},
op.#Exec & {
always: true
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"/getPods.sh",
]
env: KUBECONFIG: "/kubeconfig"
},
]
}

View File

@ -0,0 +1,26 @@
name: default
inputs:
TestConfig.awsConfig.accessKey:
secret: ENC[AES256_GCM,data:dzhlip9kKU8mMEycFjq6MobD5BA=,iv:LKeYUbXpnWIZneGs7DCLVKxv1W2aa/3EVGO4jnDlOgc=,tag:+TcxQahxFTweyoPaROTJSQ==,type:str]
TestConfig.awsConfig.secretKey:
secret: ENC[AES256_GCM,data:bu3AI5jODWv4ePvRKw2l/1UOuH07Z0/oB2hiY4QqrhTcfjdSbr6kBg==,iv:BqddzzXqvAv0cAj2SVhoFx/kUOnRsoevqMRujCINVv0=,tag:u0KjVnbN8h54CLFARJmJ0g==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzV0ZXNW5qaGNJMjF5bnBO
d1Z1RXFhSnNRM1Vwa3lyWFJ6VVFDZTQ3cUhZClh0N1lxZ3dwSFhHTjRyS092OVVj
Tkw4ZlU4S3g0T1VGS1RYYnB1dGlzbVkKLS0tIEc4T1Z3SEU2NUNhd2FkSXlIUERM
UE5Cd2VwYkd1MHlTOXNJVEU3RVpqU2sK86kXU6ZaaVHTg9BuCEcOxnDrrW00+bwu
AHttbzqYVuC3YxXjOTzAZL8aYTStk14wGdI6TirZ9pX0fyaKAfzBUQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-27T16:01:59Z"
mac: ENC[AES256_GCM,data:T+0rcT9Xi/kJ8+EzCd7ewenDmc1cH/t2MxCpf+QXkILUC/uE8OgROizDMAiUYI2HpeBfZrmUgLMVzlTZirIbC51eWLAf6itbSIGKkVuz0uSNwhRpKGAROg6U1h39Scg6RpAvpzSTZvYOx5SwP78Uc6NQdp5yTDEb+0e9Wqzu+jU=,iv:INAN+EPwBv5dWWHQnaMr4QOBQWx3WCcohORvIPrBZN8=,tag:N4vtDowFKTDSHmMob5HgCw==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -1,34 +0,0 @@
TestConfig:
awsConfig:
accessKey: ENC[AES256_GCM,data:8Qs7BEbLD/tCUuRIitE/j511Lng=,iv:rNv9rnXSvIpKeUYRqseS9aKjEG4Wim7OW0EKEbBgp+M=,tag:pll2PjARaVnRXEXKuwvxTQ==,type:str]
secretKey: ENC[AES256_GCM,data:erQRIAf41W0cDaDO3peKsT3LyBzrOE4cn9vs5OIDCeTY047x3feXsw==,iv:zISyY5zGZHfe5HZJHdfIUpX6siFIgLMrwAbZRyLH9FU=,tag:znsdNX4c6KoGdWqFbYVkfg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2021-04-21T18:01:50Z'
mac: ENC[AES256_GCM,data:B0i5IWMMqzo5M2D+FunOk+XXpHVevnLt/o0ug4ld0YWxEb2FMiAR87td3VaiA5RLdVBEdaZkLR0gNrl3fcLYMjJzndmpLF9W626aL5nk3X/WgfF7QmwUoc6mS0M6GeIB6sghzLbhdH9fFS38G7Xm/isTlnILWcbJVANhmjJ+2kU=,iv:X7httONHYQ0jwDQWawx9AaOSFUPbrFA5Bq8T5TZCgsU=,tag:n7gVHeFZPDu7tNxaYLR8og==,type:str]
pgp:
- created_at: '2021-04-21T18:01:22Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAzqVY590vudzAQ//Wl/GkApRyvWZnMPky8m/4O06NtJ9Zl4n8nXNCnWQ7gFL
Wt6y62u4mjIuIX5edRwbD726vF0MR84LxfAZ8ppw3lbnM+XDVeT12JA7VS33SOgU
oQBl4qTWrBEdVV2f83n56SvcF4YQkHjKcWWeSQZ2LGTj1jqt35trD/KzXQTwYaEi
9JX9N+NYfAhuTDsSVi+mGeQnYZS4PAxkd9rWUcTm41EWh+d7hzNtz5T1Tx+a7q+S
XnHf6hxe9Q52Lsyumihi16eExz1Ym+x16gGtP5ioSZUiO45yk5/+iihUJJE6pBMF
Tss7KjLcoVREpl506e8Gsi5HEiMxlCR6KYzDOYfr6IWe3dPPhg9xJSJBIjF7JktQ
Bvua5y18bZIrlstIHeoe1Us5wEiLQigfNLBsoEN/aCwRr8o1KGnDuBasKssRUapL
xL4TxxQdlY6TJP/c8UVWN5q4l+Phsyt12d5KtugRRMSKDn66kRbvT4ykUy23cBO7
XN1dQ+E9gyJRHCM2lPMeQsz9YlzHejJB4N+3aOlUeZH51hfVAGMuaSzjdPCHowyP
MYwg8wuasqSgNuc3sHj5J0WI1Ka14cE0O6jGlXDmviBSEyvRxovC/E/nyf80vF7n
BIG2DVJE0zYS4Ci0ebN79G0RhbxBWeF2EAPxiVbcFL0cDw8e6YcoyUiinwL1llPS
XgHZdvhkq3523wLn+XJUbc0xLK2EEZaQY9bEAeroX4fkyruCAZgxADH2JBnuO5Bc
aUBP1do4DxCBAzL3rT4uFFaiOCO5dKrliI9y6XTksRQm1nFo3SclN51SbFGlWxc=
=6cuG
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted
version: 3.6.1

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -22,7 +22,9 @@ TestS3UploadFile: {
} }
verify: #VerifyS3 & { verify: #VerifyS3 & {
file: "test.txt" config: TestConfig.awsConfig
target: deploy.target
file: "test.txt"
} }
} }
@ -36,10 +38,14 @@ TestS3UploadDir: {
} }
verifyFile: #VerifyS3 & { verifyFile: #VerifyS3 & {
file: "dirFile.txt" config: TestConfig.awsConfig
target: deploy.target
file: "dirFile.txt"
} }
verifyDir: #VerifyS3 & { verifyDir: #VerifyS3 & {
file: "foo.txt" config: TestConfig.awsConfig
target: deploy.target
file: "foo.txt"
} }
} }

View File

@ -0,0 +1,83 @@
package s3
import (
"dagger.io/aws"
"dagger.io/alpine"
"dagger.io/dagger/op"
)
#List: {
// AWS Config
config: aws.#Config
// Target S3 URL (e.g. s3://<bucket-name>/<path>/<sub-path>)
target?: string
contents: {
string
#up: [
op.#Load & {
from: aws.#CLI & {
"config": config
}
},
op.#Exec & {
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
aws s3 ls --recursive \#(target) > /contents
"""#,
]
},
op.#Export & {
source: "/contents"
format: "string"
},
]
}
}
#VerifyS3: {
file: string
config: aws.#Config
target: string
lists: #List & {
"config": config
"target": target
}
test: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "~5.1"
}
},
op.#WriteFile & {
dest: "/test"
content: lists.contents
},
op.#Exec & {
always: true
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
"grep -q \(file) /test",
]
},
]
}

View File

@ -0,0 +1,30 @@
name: default
inputs:
TestConfig.awsConfig.accessKey:
secret: ENC[AES256_GCM,data:iu6LfQNgGZUVnHVeMRYPrcBtlZk=,iv:U5PLxDKXwJnUDdk1ayFGvvJfWdVqh1PK5ujb20YYPP0=,tag:QyqIJRiR6nE16ZDV0CP7Pw==,type:str]
TestConfig.awsConfig.secretKey:
secret: ENC[AES256_GCM,data:Q/W+KH3NEouGt6C5S+KiC43837soYi2Mjb/z5K8rD9gtaNaBjjkJHg==,iv:8nGEzLXd91rF5YBZ/EdQoMN27yrpc0sgm26DEvIuSHM=,tag:/oyKl/vj5MJAm+jZMOOAuQ==,type:str]
TestDirectory:
dir:
path: ./testdata
include: []
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKeEk5MS9nVmFoOVNNOHdE
WnZCTXBWbW9LL1NJYndCYjhIM2JsNXNEUmxJCkUya0dlZjZ0dGRIM1pVdzg5eWFH
MVpiaE9PclNudGdUZm5FcytuVDZGTDAKLS0tIEQxWDdteHgzS3JkdmtNTVpxMUh1
aXlvVWJVSGNTSkVyYmpZbi9nUVJZdmMK6csXZ2RMxFw5DB+Hb2TyhyoZT8c2/z7Y
Lc9Pe8gb8aUq5Ha+wCybYvY6JWEM5A9XYJKbE7f4borTfGKS72d6pw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-27T00:13:13Z"
mac: ENC[AES256_GCM,data:uqGhc0e6mQp5kdKvJTFz+yjcc5WUtLBcsqkzh0NeJhP9nztpX1TJfqBeyGfd7pwltL6b9YXLdJx/myCMxvJ6O8bS726AxE4ogcRgUGP6d5Q5aXw9i7VkLgVKY+gJZCbT+r80RiMqm23x3CPAPNjEsPh5nfgdNsN5ltJmq7IUGj0=,iv:Mw56hEghRGw6tLP6rhe78yD/blqgX2roeQRDiJ6+kAI=,tag:qE2LtSZPxDhITtdnsvrYfA==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -1,69 +0,0 @@
package s3
import (
"dagger.io/aws"
"dagger.io/alpine"
"dagger.io/dagger/op"
)
#List: {
// AWS Config
config: aws.#Config
// Target S3 URL (e.g. s3://<bucket-name>/<path>/<sub-path>)
target?: string
// Export folder
export: "/contents"
// Script
aws.#Script & {
code: """
aws s3 ls --recursive \(target) >> /contents
"""
}
}
#VerifyS3: {
file: string
lists: #List & {
config: TestConfig.awsConfig
target: "s3://\(bucket)"
}
#CheckFiles:
"""
grep -q \(file) /test
"""
test: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "~5.1"
}
},
op.#WriteFile & {
dest: "/test"
content: lists.out
},
op.#WriteFile & {
dest: "/checkFiles.sh"
content: #CheckFiles
},
op.#Exec & {
always: true
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"/checkFiles.sh",
]
},
]
}

View File

@ -1,34 +1,23 @@
registry: registry:
username: ENC[AES256_GCM,data:8AH6p9WHidanCA==,iv:ezThCQJv+bVBf8SdfSa2HFoP+eu6IZMPl5xvMOGDcps=,tag:mzR7xTKeQNDvkyd2Dm3AKw==,type:str] username: ENC[AES256_GCM,data:YDDLkr32orAgQw==,iv:ezThCQJv+bVBf8SdfSa2HFoP+eu6IZMPl5xvMOGDcps=,tag:sEV9Sonc9rjDbxXsV+UBIA==,type:str]
secret: ENC[AES256_GCM,data:GtuaBAhFBw2JFaeuOm6mUr3m1j5fvCJjcWAzjsdU2xASFxwO,iv:YAXcRzBoemmef5PBdAOBa5acNPo4BoKH7Ngud/CWYfA=,tag:MCCUCOSutjRCI92raYrxdg==,type:str] secret: ENC[AES256_GCM,data:moBq7PwFdtL/Z58ez+V1gR8QJsFRZEMsF82H/W6aJgf8Xdw8,iv:YAXcRzBoemmef5PBdAOBa5acNPo4BoKH7Ngud/CWYfA=,tag:LFkJvUZdltgHJ8TKVEeS/Q==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age:
lastmodified: "2021-04-27T00:59:33Z" - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
mac: ENC[AES256_GCM,data:qk+oo4m5OpfuQ+R3pZUuvn+gqAk15OAJzOULrlYqt1FIDRk/Q5ah5QpIbVxeP1EDVyuY/V/E0ZngRlSV7Dyx6Cp/moMd8AFBHNgnTB+Lq+NmZ9HR1QMOxpbMpJmUGn7MqQ1Ys4wy0p2q2Y2+TuUpKwmRGJbGVYEVmqvV5OT3jhc=,iv:QsUFa2GVzy6iqqLXRz8HascQZPIIzKBhxHdlabov02k=,tag:7lk63FeXsOlTCgfmWd7zrg==,type:str]
pgp:
- created_at: "2021-03-18T22:59:59Z"
enc: | enc: |
-----BEGIN PGP MESSAGE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGVmQxTXNSeU1scWJvVDFJ
hQIMAzqVY590vudzAQ//etnfnpfCo9rAkctR+Fwg/7VdVL3Rov+6gnyjUnoN1BS1 cExOL3AvR1JRRWp0cFFRWGtvQ1VKc2t1SUVFClVCS1hpN1dNTktoaWZ3R09OMFVM
8jnBF/86AZ7uK89dTcTZCsK1hKPxeYg1kJTKpA+zfDORupzTWcMrRyjwNk5wQ2Vg STRyWmtHRVROMW1Oa28yQkMwOHd1UUUKLS0tIE5LL1pEb1dMSEVXTHBsNlJxOTcr
N1adUwFsBQpk8WptpsU/ro6+3yH+Nn35begs6hP2fH/EQ9XOxw5gY0kp0AFjGaKJ U2FyQUtYcXVVVTlVcW5zRXh5aUk3RUUKGiWb9jSl5xRHQxB56LtNclV5Jhs50sS7
tRZVrr3f2hpLESo6LILRO97UXZiGcwTn5onslECL92260cU1nqEQp+ESK7XrdYIG SAOBWgaYPjLpsI1oxgXf+B1FgBUEt3EMccrWRW85VvnOKOAUAJ53pQ==
99oM3eXEraKw4WuQDaDE6U135aUl6vIJWD1JZzyr3RW3+5O9pn5rpN3Wc0TbDR6+ -----END AGE ENCRYPTED FILE-----
9Fs/TjuA1h5eJzbt+lkA74BtxPOBv9O7HJnWJpXjiG0VUGHdFXoq5Tr5Ol68RQxa lastmodified: "2021-05-28T20:49:27Z"
BWe7IfTO6FHN0xOl1dY7cn5jtf+xlFjL86s9OkrJUFa9lbQx8L/QPCeA2Xiu4tpW mac: ENC[AES256_GCM,data:we6IaVqfT6KZ4s97JbdFCbxL2zotojLRLEbmgwEAfBhz4KAitulRItMn4I6aD1dEIwYGAFtQEcf+Wqz2yT7JC6iz1s2zNtGIaMbxxQZD6EQcJvNmY3vzqC4SKf0cRENGZWI5OscH9VVenTmOAxwwWvp9W4J52d2w9FAD9+vCl/c=,iv:vf8mZwr+z7DjCVHaRbk8jQO9/pso5INy/FmCPq/xlzo=,tag:sgSvlksSOVq5LU0ycAsXxw==,type:str]
+wTSel13k8Uv/JSGgLwSohW6N4XTQYdxPkO+a1V08adwFBXaGgqxfg0rNehcS5fp pgp: []
y3TEq84cOlBsaI+rYpnOTPEajtYWfTe8WFf+lBOn1vZ9EiupjZtefGX2MIWPXoaK
kVBgRvzjp4/BY68yRvdi5sZFd2nakl+DOXzouuFbzsOkxL3o9FA9aCVsXtFqqzSG
Hvq4ZJ5ivXf6vQf+s7Tgc4qxW2CQwIPZVkHhQossrWgtkQ4WDAyzfhF0YuhEnpLS
XgGNLr82LMVmempaJd7GfAR2nwGnLUTYny1KoiW/1ie6DPwLZBX/UxPOplaS5wYH
Xd3gV3smg5xZ7/rfvzKTzJ1a5yH6D3xI05UtnUWdqojONcXS9NS+P7RArngJwSs=
=m0OS
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.7.1 version: 3.7.1

View File

@ -11,7 +11,7 @@ source: dagger.#Artifact
registry: { registry: {
username: string username: string
secret: dagger.#Secret secret: string
} }
TestPushAndPull: { TestPushAndPull: {

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,28 @@
name: default
inputs:
TestConfig.gcpConfig.project:
text: dagger-ci
TestConfig.gcpConfig.region:
text: us-west2-a
TestConfig.gcpConfig.serviceKey:
secret: ENC[AES256_GCM,data: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,iv:tPbOGayR7NiXcuHWjX0pX/nSitOxmsr4qqrc6irlIJI=,tag:apejA4UTYTuwT4CUSeoaRQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCRThSTEE1Rm5HU2Y2NkJZ
SEd2blAyeEVnMHBqRGxXMEQ3TGFzWTBwd1EwCnA0OFVmTCsxSmpNV29adGt2ZHFH
WE9vN1ZoNENFV2t1TGVuZkdwVndNbVUKLS0tIGpHZEptYWxEZVNjcXF4NkoyWHRv
ZXd6Qmd1YUtxMnVTVkYybWgrV3pVK2MKowMeOZU3j3BxERT0DwhQYCGUDBK6gCdo
WByubiBATdsb7h7ytCC4HutWppynK4MpU+Ya9NP83AZuXo+Wa2u6aQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-28T02:07:09Z"
mac: ENC[AES256_GCM,data:QqbgWep3l7dIfE4imJ3SKsMdexh7DgUvjtGwSgKbHHnT0p2MwIdFMY7pB0ZJvlc3ZwQyioT3wqF9xgn4U60a4piGtDYsyWjZn52tQAPy0p9c+sOHn+WlFVu1FJeljU4Q3mlEqdA6g993nsbJp9RnNShpc65rQXUMLkw2lXhOAak=,iv:1pp1D1fUFGI+Kn/H2efaqroJV+rzJRGmWo2ZTseTDis=,tag:ePCkD/G2KEbN7cxiMpy9fg==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,28 @@
name: default
inputs:
TestConfig.gcpConfig.project:
text: dagger-ci
TestConfig.gcpConfig.region:
text: us-west2-a
TestConfig.gcpConfig.serviceKey:
secret: ENC[AES256_GCM,data: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,iv:tPbOGayR7NiXcuHWjX0pX/nSitOxmsr4qqrc6irlIJI=,tag:apejA4UTYTuwT4CUSeoaRQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCRThSTEE1Rm5HU2Y2NkJZ
SEd2blAyeEVnMHBqRGxXMEQ3TGFzWTBwd1EwCnA0OFVmTCsxSmpNV29adGt2ZHFH
WE9vN1ZoNENFV2t1TGVuZkdwVndNbVUKLS0tIGpHZEptYWxEZVNjcXF4NkoyWHRv
ZXd6Qmd1YUtxMnVTVkYybWgrV3pVK2MKowMeOZU3j3BxERT0DwhQYCGUDBK6gCdo
WByubiBATdsb7h7ytCC4HutWppynK4MpU+Ya9NP83AZuXo+Wa2u6aQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-28T02:07:09Z"
mac: ENC[AES256_GCM,data:QqbgWep3l7dIfE4imJ3SKsMdexh7DgUvjtGwSgKbHHnT0p2MwIdFMY7pB0ZJvlc3ZwQyioT3wqF9xgn4U60a4piGtDYsyWjZn52tQAPy0p9c+sOHn+WlFVu1FJeljU4Q3mlEqdA6g993nsbJp9RnNShpc65rQXUMLkw2lXhOAak=,iv:1pp1D1fUFGI+Kn/H2efaqroJV+rzJRGmWo2ZTseTDis=,tag:ePCkD/G2KEbN7cxiMpy9fg==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -1,36 +0,0 @@
TestConfig:
gcpConfig:
project: ENC[AES256_GCM,data:QVioZWWseno1,iv:WHdf8+4/rHg/NUug6GW4lFkJsUU4VhpE489myNTRnr4=,tag:7uUBSj6ncrfhmbtLNxURFA==,type:str]
serviceKey: ENC[AES256_GCM,data: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,iv:M1AGMV/mWY3h+7DuCegKDG14ooHvrylJ1IGhzfW4g+4=,tag:DaZ1Y0pPsYU8C2EkavVQrw==,type:str]
region: ENC[AES256_GCM,data:q77ffNChCAOCeA==,iv:01JZwKtBQd4hur8M6xvIul66FhN33ulHzRnFeQy3QIQ=,tag:asvkETPb1cnukzk6zusxfg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2021-05-19T23:31:38Z"
mac: ENC[AES256_GCM,data:7t/Jd78t/ExyLtg5B3J+8vPPxCc9UWa6QBBK0yQxKUIAVJ31loYeyOw1pULMpNRST2EQXZ899Ejdp3eZAHpx7gSc6Sg9Ep5Bcm0Hy1MJ1V07AYr+6y6KVyUToVcWQhzC0IV8ud9g8w/HAP3VY6yOGjgkKVcJXozliJZ1HrnWIww=,iv:K+Lz17H3OoN9symOQ8tF/iaov6pxxduI7cvfSS3WhIA=,tag:9sOzCGy0NiG5utWt+9wTZw==,type:str]
pgp:
- created_at: "2021-04-21T18:01:22Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAzqVY590vudzAQ//Wl/GkApRyvWZnMPky8m/4O06NtJ9Zl4n8nXNCnWQ7gFL
Wt6y62u4mjIuIX5edRwbD726vF0MR84LxfAZ8ppw3lbnM+XDVeT12JA7VS33SOgU
oQBl4qTWrBEdVV2f83n56SvcF4YQkHjKcWWeSQZ2LGTj1jqt35trD/KzXQTwYaEi
9JX9N+NYfAhuTDsSVi+mGeQnYZS4PAxkd9rWUcTm41EWh+d7hzNtz5T1Tx+a7q+S
XnHf6hxe9Q52Lsyumihi16eExz1Ym+x16gGtP5ioSZUiO45yk5/+iihUJJE6pBMF
Tss7KjLcoVREpl506e8Gsi5HEiMxlCR6KYzDOYfr6IWe3dPPhg9xJSJBIjF7JktQ
Bvua5y18bZIrlstIHeoe1Us5wEiLQigfNLBsoEN/aCwRr8o1KGnDuBasKssRUapL
xL4TxxQdlY6TJP/c8UVWN5q4l+Phsyt12d5KtugRRMSKDn66kRbvT4ykUy23cBO7
XN1dQ+E9gyJRHCM2lPMeQsz9YlzHejJB4N+3aOlUeZH51hfVAGMuaSzjdPCHowyP
MYwg8wuasqSgNuc3sHj5J0WI1Ka14cE0O6jGlXDmviBSEyvRxovC/E/nyf80vF7n
BIG2DVJE0zYS4Ci0ebN79G0RhbxBWeF2EAPxiVbcFL0cDw8e6YcoyUiinwL1llPS
XgHZdvhkq3523wLn+XJUbc0xLK2EEZaQY9bEAeroX4fkyruCAZgxADH2JBnuO5Bc
aUBP1do4DxCBAzL3rT4uFFaiOCO5dKrliI9y6XTksRQm1nFo3SclN51SbFGlWxc=
=6cuG
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted
version: 3.7.1

View File

@ -0,0 +1,2 @@
# dagger state
state/**

View File

@ -0,0 +1,46 @@
package netlify
import (
"dagger.io/dagger/op"
"dagger.io/alpine"
"dagger.io/netlify"
)
TestNetlify: {
// Generate a website containing the random number
html: #up: [
op.#WriteFile & {
content: random
dest: "index.html"
},
]
// Deploy to netlify
deploy: netlify.#Site & {
contents: html
name: "dagger-test"
}
// Check if the deployed site has the random marker
check: #up: [
op.#Load & {
from: alpine.#Image & {
package: bash: "=~5.1"
package: curl: true
}
},
op.#Exec & {
args: [
"/bin/bash",
"--noprofile",
"--norc",
"-eo",
"pipefail",
"-c",
#"""
test "$(curl \#(deploy.deployUrl))" = "\#(random)"
"""#,
]
},
]
}

View File

@ -0,0 +1,20 @@
package netlify
import (
"dagger.io/alpine"
"dagger.io/dagger/op"
)
// Generate a random number
random: {
string
#up: [
op.#Load & {from: alpine.#Image},
op.#Exec & {
args: ["sh", "-c", "cat /dev/urandom | tr -dc 'a-z' | fold -w 10 | head -n 1 | tr -d '\n' > /rand"]
},
op.#Export & {
source: "/rand"
},
]
}

View File

@ -0,0 +1,26 @@
name: default
inputs:
TestNetlify.deploy.account.name:
text: blocklayer
TestNetlify.deploy.account.token:
secret: ENC[AES256_GCM,data:oWKi8eqTUEs+YClokLKeAKsEj3qae4yQTn/67u6ga4Ptcq4+MyYS/6wAUg==,iv:Xfw+L/4p7vO+jb/EVyYOvsIZ9KxZbi30ms2Ckg4E8cE=,tag:G4EBBer04D6FHFP9e+feTw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwWHFLRUtscWVma0lQM3Qv
M2czUFJhSEpnczdJTWhadnJHOWowaXd1dWtJCmk3aU15NDJYcmtUOE5pZ0lIQzRu
dTYvRFdsM0ZoUjFWSG91UnZRVWdvZjgKLS0tIENhK2VWNHByY3hYNUVmWDRmOUFM
SEdUK2RsaUxuVWg2aXUwdVJ0eUtrWWMKWkQDBuL5e4QDx5Wy6+fHiD+J4fp7QdMm
lsqgmxRvJMWgEvm1U+hDAo/Pkn8PFUFJf0KxEvkdF4qGuguQePgzFQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-28T20:40:41Z"
mac: ENC[AES256_GCM,data:12suvaaHfmdt0jaldFmaixGvWUbl0RP/By3l1S9XiUGLbB4tNfV65qsWv9BnjfD//98iV21dYkpCbXPQAITjM0MOGcrkZ9u3lDrmD2dTybHgxgniYJVe/X7BA5Y8uw4a3g+k+HqV5Z8i/iMGCEBbqakt20rNXqzGAFiWJfRcPGo=,iv:6TdOLjFJxn1uDsCLRNGpyUSiLszKHctN0crywXB5PfQ=,tag:XGcPX6lGeJcigxvOuiqyyw==,type:str]
pgp: []
encrypted_suffix: secret
version: 3.7.1

View File

@ -1,35 +0,0 @@
TestNetlify:
deploy:
account:
name: ENC[AES256_GCM,data:AupEMRKMWvb8Wg==,iv:M4ni+CrI0udcYqgSTciuYZOVyZkTUVSrluSwJFIjqiE=,tag:dztVg8S/db5uI0cC7rivQg==,type:str]
token: ENC[AES256_GCM,data:W7Y1Qf4w5gn5OeGigY3a35VFP9THOZ7Hu9L5l84afwEpYlAQm+M8C67CHA==,iv:Jey3UX/3DihTGG87aFU2FWzEIuXlQ+pboxTd8Gx5gNY=,tag:LnpTzsVzTZkkk+jsbtkpKw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2021-03-19T00:15:11Z'
mac: ENC[AES256_GCM,data:bXUJxpw4wIzqzNRjYnyxiYqfTCk78YGOI8CdyIjhFsVgEhla8FmS/CCeUlEunfbTwaYQkWx+Uodz8MVk1yGcvjOl6KQvcIL8/U2uA3WYJaHI94ZdlE1J+YlLOdQR8D+RJbDkJiEhQKek2d21CM3A8njx5uUvWkzQE43lmeQAKgI=,iv:kITjaVpxc3vqLPl+mhufC5mADNk+86+u664jltBN9ro=,tag:j8/xMpLjgI8TvNb+O21C4g==,type:str]
pgp:
- created_at: '2021-03-19T00:15:11Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAzqVY590vudzAQ//XsnreKKngyWdere1fMGDZxJgS7+e6dkg/2NfH58gcHvp
qv3/MqYN9rz/WhmpbZTdkahxuNOrsVjGT1hcBjjqgkK5wBiUqTaEGR6GKd1bhZ5o
t8oyYEPu4hUdzD52bcO/sapTymYSA6tc9XsGaMlferzsZVZ2T25nXpFrQ8gcRtbi
12Tmx6FbiaqfOcNjCgcyQ7sS1oDLSXgKtj9yS8rC3LuD1ZR9HgeqBWycH318hFEH
Dkj0FlmVhF6cOZGK5WgUR7ibp5v44ta+A94HXIyUbEfN2yCo1iLxJRjH5s/S0xsJ
CwssAK3NtSxnxTk9UgX//pyl29WX2Bc3tbSEYn1pelHvWNfb6zWUMmc4O0pTtLJO
AFjeZvmB33ry1AFkuy+5NTp2B66NiiNTa7ojamTF3i2d6zVCGUJ9HO560i3pURax
7YM1fsexBk0P6GohEdgWwx41BGqd8jt0vmrhrVIXeqDiykwYNUAkv55PTDWmG8MJ
bUNAEsKOaDHT0MaIGIqAmIdIWm//IdmK7sL8r9T3mnBQovtANRV1A+ejSWZF0fbG
DY8b4knVJVL8BMu0QnToSyHDChgAqr2liciZ+Cmx72hTVi8RkJzsBXMtjNG6bEiK
R8eBUueEsnU44PkHCJBg2gs3v+m2KUjlVbwNLFDG6/xFUs21j6bV7dhn2l3RZSPS
XgE0hKI6GK8uyu24E8mJ+pYZF4CYIgkTbyTN2fn64N3aNMn8L1bHonpXxexcnWaI
46fatc3YtQg2mgoeNhvM7xtJYJU5RwfaTsjdjecK9jBKWiXXlgoLBwHJgkB03YQ=
=Lrp5
-----END PGP MESSAGE-----
fp: 6CB37404020B5F0A0B41B5BB225EBAB0B936AC65
unencrypted_suffix: _unencrypted
version: 3.6.1

View File

@ -0,0 +1,24 @@
TestConfig:
awsConfig:
accessKey: ENC[AES256_GCM,data:cZLf9D1ymnU4A44oGiQ4fFKdEB0=,iv:rNv9rnXSvIpKeUYRqseS9aKjEG4Wim7OW0EKEbBgp+M=,tag:cOzI4KsDgCgi/w7ByFKJJw==,type:str]
secretKey: ENC[AES256_GCM,data:ZFIHfnQYYu7ZhoXogVIHbd2wakBTw9D0TiHeadSKaYAQemCun/egNg==,iv:zISyY5zGZHfe5HZJHdfIUpX6siFIgLMrwAbZRyLH9FU=,tag:uD+1eLHY/AKR9vnpyBh+GQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPdU5ENVpScm0yd2RXWjRJ
aSsxWTNvSHBBeU94Z2ZKNjhXdzJHZGNybXkwCk9FVW5EM21LSTRHMkE5VG1SRFpL
ZGUyOHl3MEU3M3ZXTzBqSlExTU1uVTgKLS0tIDZRVDJOaEVZVnVSalRKMUVTTytV
ZWRONHhmOEJVd1lqM1NkMFdSNHU2THMKSjtxHeq/ZSgpXrevLH4AVYyRh4jO6qjT
J301rFx0Cu5qeSIhRiG54Pse83GD+fObDhfH0nPf5HZttDZxrISUdg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-05-28T20:45:06Z"
mac: ENC[AES256_GCM,data:7b6X10McAD1qvsS3ZFWeteP7zLC6IAo6NdFjvaX1iyrjoZ+fT8hNkIPVKyfPFTqZzNIZ7qEYJO2PKrTjbhf6a1LEsL9gtfoX4JwINDk66TgIsJsvdp4TRIlEKoRSKK08zc+A5YFAtD1Pj+a3+NnF32ZUsoH+jqSixH2hK51RI0U=,iv:JKeSA0bp+QBE8H/kS/eIL47k1Bsg4L0q/YU4OlJmIKU=,tag:f3gzp/Nv4p4DajNfoAicAg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.7.1

View File

@ -4,13 +4,14 @@ import (
"dagger.io/dagger" "dagger.io/dagger"
"dagger.io/terraform" "dagger.io/terraform"
"dagger.io/aws"
) )
TestData: dagger.#Artifact TestData: dagger.#Artifact
TestConfig: awsConfig: aws.#Config & { TestConfig: awsConfig: {
region: "us-east-2" accessKey: string
secretkey: string
region: "us-east-2"
} }
TestTerraform: apply: terraform.#Configuration & { TestTerraform: apply: terraform.#Configuration & {