Merge pull request #476 from aluzzardi/gke
stdlib: add GKE & GCR support
This commit is contained in:
commit
7104600705
53
stdlib/gcp/gcloud.cue
Normal file
53
stdlib/gcp/gcloud.cue
Normal file
@ -0,0 +1,53 @@
|
||||
package gcp
|
||||
|
||||
import (
|
||||
"dagger.io/dagger/op"
|
||||
"dagger.io/alpine"
|
||||
)
|
||||
|
||||
// Re-usable gcloud component
|
||||
#GCloud: {
|
||||
config: #Config
|
||||
version: string | *"288.0.0"
|
||||
package: [string]: string
|
||||
|
||||
#up: [
|
||||
op.#Load & {
|
||||
from: alpine.#Image & {
|
||||
"package": package
|
||||
"package": bash: "=~5.1"
|
||||
"package": python3: "=~3.8"
|
||||
"package": jq: "=~1.6"
|
||||
"package": curl: "=~7.76"
|
||||
}
|
||||
},
|
||||
|
||||
// Install the gcloud cli
|
||||
op.#Exec & {
|
||||
args: ["sh", "-c",
|
||||
#"""
|
||||
curl -sfL https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-\#(version)-linux-x86_64.tar.gz | tar -C /usr/local -zx
|
||||
ln -s /usr/local/google-cloud-sdk/bin/gcloud /usr/local/bin
|
||||
"""#,
|
||||
]
|
||||
},
|
||||
|
||||
// Setup auth
|
||||
op.#WriteFile & {
|
||||
dest: "/service_key"
|
||||
content: config.serviceKey
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
args: ["gcloud", "-q", "auth", "activate-service-account", "--key-file=/service_key"]
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
args: ["gcloud", "-q", "config", "set", "project", config.project]
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
args: ["gcloud", "-q", "config", "set", "compute/zone", config.region]
|
||||
},
|
||||
]
|
||||
}
|
15
stdlib/gcp/gcp.cue
Normal file
15
stdlib/gcp/gcp.cue
Normal file
@ -0,0 +1,15 @@
|
||||
package gcp
|
||||
|
||||
import (
|
||||
"dagger.io/dagger"
|
||||
)
|
||||
|
||||
// Base Google Cloud Config
|
||||
#Config: {
|
||||
// GCP region
|
||||
region: string
|
||||
// GCP projcet
|
||||
project: string
|
||||
// GCP service key
|
||||
serviceKey: dagger.#Secret
|
||||
}
|
44
stdlib/gcp/gcr/gcr.cue
Normal file
44
stdlib/gcp/gcr/gcr.cue
Normal file
@ -0,0 +1,44 @@
|
||||
package gcr
|
||||
|
||||
import (
|
||||
"dagger.io/dagger/op"
|
||||
"dagger.io/gcp"
|
||||
)
|
||||
|
||||
// Credentials retriever for GCR
|
||||
#Credentials: {
|
||||
// GCP Config
|
||||
config: gcp.#Config
|
||||
|
||||
// GCR credentials
|
||||
username: "oauth2accesstoken"
|
||||
secret: {
|
||||
string
|
||||
|
||||
#up: [
|
||||
op.#Load & {
|
||||
from: gcp.#GCloud & {
|
||||
"config": config
|
||||
}
|
||||
},
|
||||
op.#Exec & {
|
||||
always: true
|
||||
args: [
|
||||
"/bin/bash",
|
||||
"--noprofile",
|
||||
"--norc",
|
||||
"-eo",
|
||||
"pipefail",
|
||||
"-c",
|
||||
#"""
|
||||
printf $(gcloud auth print-access-token) > /token.txt
|
||||
"""#,
|
||||
]
|
||||
},
|
||||
|
||||
op.#Export & {
|
||||
source: "/token.txt"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
84
stdlib/gcp/gke/gke.cue
Normal file
84
stdlib/gcp/gke/gke.cue
Normal file
@ -0,0 +1,84 @@
|
||||
package gke
|
||||
|
||||
import (
|
||||
"dagger.io/dagger/op"
|
||||
"dagger.io/gcp"
|
||||
)
|
||||
|
||||
// KubeConfig config outputs a valid kube-auth-config for kubectl client
|
||||
#KubeConfig: {
|
||||
// GCP Config
|
||||
config: gcp.#Config
|
||||
|
||||
// GKE cluster name
|
||||
clusterName: string
|
||||
|
||||
// Kubectl version
|
||||
version: *"v1.19.9" | string
|
||||
|
||||
// kubeconfig is the generated kube configuration file
|
||||
kubeconfig: {
|
||||
// FIXME There is a problem with dagger.#Secret type
|
||||
string
|
||||
|
||||
#up: [
|
||||
op.#Load & {
|
||||
from: gcp.#GCloud & {
|
||||
"config": config
|
||||
}
|
||||
},
|
||||
|
||||
op.#WriteFile & {
|
||||
dest: "/entrypoint.sh"
|
||||
content: #Code
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
always: true
|
||||
args: [
|
||||
"/bin/bash",
|
||||
"--noprofile",
|
||||
"--norc",
|
||||
"-eo",
|
||||
"pipefail",
|
||||
"/entrypoint.sh",
|
||||
]
|
||||
env: {
|
||||
GKE_CLUSTER: clusterName
|
||||
KUBECTL_VERSION: version
|
||||
}
|
||||
mount: "/cache/bin": "cache"
|
||||
},
|
||||
op.#Export & {
|
||||
source: "/kubeconfig"
|
||||
format: "string"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#Code: #"""
|
||||
[ -e /cache/bin/kubectl ] || {
|
||||
curl -sfL https://dl.k8s.io/${KUBECTL_VERSION}/bin/linux/amd64/kubectl -o /cache/bin/kubectl \
|
||||
&& chmod +x /cache/bin/kubectl
|
||||
}
|
||||
|
||||
export KUBECONFIG=/kubeconfig
|
||||
export PATH="$PATH:/cache/bin"
|
||||
|
||||
# Generate a kube configiration
|
||||
gcloud -q container clusters get-credentials "$GKE_CLUSTER"
|
||||
|
||||
# Figure out the kubernetes username
|
||||
CONTEXT="$(kubectl config current-context)"
|
||||
USER="$(kubectl config view -o json | \
|
||||
jq -r ".contexts[] | select(.name==\"$CONTEXT\") | .context.user")"
|
||||
|
||||
# Grab a kubernetes access token
|
||||
ACCESS_TOKEN="$(gcloud -q config config-helper --format json --min-expiry 1h | \
|
||||
jq -r .credential.access_token)"
|
||||
|
||||
# Remove the user config and replace it with the token
|
||||
kubectl config unset "users.${USER}"
|
||||
kubectl config set-credentials "$USER" --token "$ACCESS_TOKEN"
|
||||
"""#
|
@ -42,24 +42,36 @@ setup() {
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/kubernetes/helm --input-dir kubeconfig=~/.kube --input-dir TestHelmSimpleChart.deploy.chartSource="$TESTDIR"/stdlib/kubernetes/helm/testdata/mychart
|
||||
}
|
||||
|
||||
@test "stdlib: s3" {
|
||||
@test "stdlib: aws: s3" {
|
||||
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/aws/s3 --input-dir TestDirectory="$TESTDIR"/stdlib/aws/s3/testdata --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
}
|
||||
|
||||
@test "stdlib: aws" {
|
||||
@test "stdlib: aws: eks" {
|
||||
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/aws/eks --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
}
|
||||
|
||||
@test "stdlib: ecr" {
|
||||
@test "stdlib: aws: ecr" {
|
||||
skip_unless_secrets_available "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/aws/ecr --input-yaml "$TESTDIR"/stdlib/aws/inputs.yaml
|
||||
}
|
||||
|
||||
@test "stdlib: gcp: gke" {
|
||||
skip_unless_secrets_available "$TESTDIR"/stdlib/gcp/inputs.yaml
|
||||
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/gcp/gke --input-yaml "$TESTDIR"/stdlib/gcp/inputs.yaml
|
||||
}
|
||||
|
||||
@test "stdlib: gcp: gcr" {
|
||||
skip_unless_secrets_available "$TESTDIR"/stdlib/gcp/inputs.yaml
|
||||
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/gcp/gcr --input-yaml "$TESTDIR"/stdlib/gcp/inputs.yaml
|
||||
}
|
||||
|
||||
@test "stdlib: docker-build" {
|
||||
"$DAGGER" compute "$TESTDIR"/stdlib/docker/build/ --input-dir source="$TESTDIR"/stdlib/docker/build
|
||||
}
|
||||
|
96
tests/stdlib/gcp/gcr/gcr.cue
Normal file
96
tests/stdlib/gcp/gcr/gcr.cue
Normal file
@ -0,0 +1,96 @@
|
||||
package gcr
|
||||
|
||||
import (
|
||||
"dagger.io/gcp"
|
||||
"dagger.io/gcp/gcr"
|
||||
"dagger.io/alpine"
|
||||
"dagger.io/dagger/op"
|
||||
)
|
||||
|
||||
TestConfig: gcpConfig: gcp.#Config
|
||||
|
||||
// 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"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
TestGCR: {
|
||||
repository: "gcr.io/dagger-ci/test"
|
||||
tag: "test-gcr-\(random)"
|
||||
|
||||
creds: gcr.#Credentials & {
|
||||
config: TestConfig.gcpConfig
|
||||
}
|
||||
|
||||
push: {
|
||||
ref: "\(repository):\(tag)"
|
||||
|
||||
#up: [
|
||||
op.#DockerBuild & {
|
||||
dockerfile: """
|
||||
FROM alpine
|
||||
RUN echo \(random) > /test
|
||||
"""
|
||||
},
|
||||
|
||||
op.#DockerLogin & {
|
||||
target: repository
|
||||
username: creds.username
|
||||
secret: creds.secret
|
||||
},
|
||||
|
||||
op.#PushContainer & {
|
||||
"ref": ref
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
pull: #up: [
|
||||
op.#DockerLogin & {
|
||||
target: push.ref
|
||||
username: creds.username
|
||||
secret: creds.secret
|
||||
},
|
||||
|
||||
op.#FetchContainer & {
|
||||
ref: push.ref
|
||||
},
|
||||
]
|
||||
|
||||
verify: #up: [
|
||||
op.#Load & {
|
||||
from: pull
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
always: true
|
||||
args: [
|
||||
"sh", "-c", "test $(cat test) = \(random)",
|
||||
]
|
||||
},
|
||||
]
|
||||
|
||||
verifyBuild: #up: [
|
||||
op.#DockerLogin & {
|
||||
target: push.ref
|
||||
username: creds.username
|
||||
secret: creds.secret
|
||||
},
|
||||
|
||||
op.#DockerBuild & {
|
||||
dockerfile: #"""
|
||||
FROM \#(push.ref)
|
||||
RUN test $(cat test) = \#(random)
|
||||
"""#
|
||||
},
|
||||
]
|
||||
}
|
32
tests/stdlib/gcp/gke/gke.cue
Normal file
32
tests/stdlib/gcp/gke/gke.cue
Normal file
@ -0,0 +1,32 @@
|
||||
package gke
|
||||
|
||||
import (
|
||||
"dagger.io/gcp"
|
||||
"dagger.io/gcp/gke"
|
||||
"dagger.io/kubernetes"
|
||||
"dagger.io/dagger/op"
|
||||
)
|
||||
|
||||
TestConfig: gcpConfig: gcp.#Config
|
||||
|
||||
TestCluster: gke.#KubeConfig & {
|
||||
config: TestConfig.gcpConfig
|
||||
clusterName: "test-cluster"
|
||||
}
|
||||
|
||||
TestGKE: #up: [
|
||||
op.#Load & {
|
||||
from: kubernetes.#Kubectl
|
||||
},
|
||||
|
||||
op.#WriteFile & {
|
||||
dest: "/kubeconfig"
|
||||
content: TestCluster.kubeconfig
|
||||
},
|
||||
|
||||
op.#Exec & {
|
||||
always: true
|
||||
args: ["kubectl", "get", "nodes"]
|
||||
env: KUBECONFIG: "/kubeconfig"
|
||||
},
|
||||
]
|
36
tests/stdlib/gcp/inputs.yaml
Normal file
36
tests/stdlib/gcp/inputs.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
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
|
Reference in New Issue
Block a user