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 AWS CLI and environment patch #20

Merged
merged 9 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ ARG GO_VERSION=1
# architecture that we're building the function for.
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION} AS build

RUN apt-get update && apt-get install -y coreutils jq unzip zsh
RUN mkdir /scripts && chown 2000:2000 /scripts
RUN apt-get update && apt-get install -y coreutils jq unzip zsh less
RUN mkdir /scripts /.aws && chown 2000:2000 /scripts /.aws

# TODO: Install awscli, gcloud
# RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip" && \
# unzip "/tmp/awscliv2.zip" && \
# ./aws/install
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip" && \
unzip "/tmp/awscliv2.zip" && \
./aws/install

WORKDIR /fn

Expand Down Expand Up @@ -52,6 +51,7 @@ FROM gcr.io/distroless/python3-debian12 AS image

WORKDIR /
COPY --from=build --chown=2000:2000 /scripts /scripts
COPY --from=build --chown=2000:2000 /.aws /.aws

COPY --from=build /bin /bin
COPY --from=build /etc /etc
Expand Down
5 changes: 5 additions & 0 deletions air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# air.toml
root = "."
tmp_dir = "tmp"
build_cmd = "go build -o ./tmp/main ."
run_cmd = "./tmp/main"
39 changes: 39 additions & 0 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ package main

import (
"encoding/json"
"fmt"
"os"
"regexp"

"github.com/crossplane-contrib/function-shell/input/v1alpha1"
"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"
"github.com/crossplane/function-sdk-go/request"
"github.com/crossplane/function-sdk-go/resource"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func addShellEnvVarsFromRef(envVarsRef v1alpha1.ShellEnvVarsRef, shellEnvVars map[string]string) (map[string]string, error) {
Expand All @@ -19,3 +27,34 @@ func addShellEnvVarsFromRef(envVarsRef v1alpha1.ShellEnvVarsRef, shellEnvVars ma
}
return shellEnvVars, nil
}

func fromValueRef(req *fnv1beta1.RunFunctionRequest, path string) (string, error) {
humoflife marked this conversation as resolved.
Show resolved Hide resolved
// Check for context key presence and capture context key and path
contextRegex := regexp.MustCompile(`^context\[(.+?)].(.+)$`)
if match := contextRegex.FindStringSubmatch(path); match != nil {
if v, ok := request.GetContextKey(req, match[1]); ok {
context := &unstructured.Unstructured{}
if err := resource.AsObject(v.GetStructValue(), context); err != nil {
return "", errors.Wrapf(err, "cannot convert context to %s", v)
}
value, err := fieldpath.Pave(context.Object).GetValue(match[2])
if err != nil {
return "", errors.Wrapf(err, "cannot get context value at %s", match[2])
}
return fmt.Sprintf("%v", value), nil
}

} else {
oxr, err := request.GetObservedCompositeResource(req)
if err != nil {
return "", errors.Wrapf(err, "cannot get observed composite resource from %T", req)
}
value, err := oxr.Resource.GetValue(path)
if err != nil {
return "", errors.Wrapf(err, "cannot get observed composite value at %s", path)
}
return fmt.Sprintf("%v", value), nil

}
return "", nil
}
48 changes: 48 additions & 0 deletions example/aws/composition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: shell-example
spec:
compositeTypeRef:
apiVersion: example.crossplane.io/v1
kind: XR
mode: Pipeline
pipeline:
- step: pull-extra-resources
functionRef:
name: function-extra-resources
input:
apiVersion: extra-resources.fn.crossplane.io/v1beta1
kind: Input
spec:
extraResources:
- kind: ProviderConfig
into: ProviderConfig
apiVersion: aws.upbound.io/v1beta1
type: Selector
selector:
maxMatch: 1
minMatch: 1
matchLabels:
- key: account
type: Value
value: demo
- step: shell
functionRef:
name: function-shell
input:
apiVersion: shell.fn.crossplane.io/v1alpha1
kind: Parameters
shellEnvVars:
- key: AWS_ROLE_ARN
humoflife marked this conversation as resolved.
Show resolved Hide resolved
value: arn:aws:iam::00000001:role/Crossplane
- key: AWS_ASSUME_ROLE_ARN
valueRef: "context[apiextensions.crossplane.io/extra-resources].ProviderConfig[0].spec.assumeRoleChain[0].roleARN"
humoflife marked this conversation as resolved.
Show resolved Hide resolved
shellCommand: |
ASSUME_ROLE_OUTPUT=$(aws sts assume-role --role-arn $AWS_ASSUME_ROLE_ARN --role-session-name "function-shell")
export AWS_ACCESS_KEY_ID=$(echo $ASSUME_ROLE_OUTPUT | grep -o '"AccessKeyId": "[^"]*"' | cut -d'"' -f4)
export AWS_SECRET_ACCESS_KEY=$(echo $ASSUME_ROLE_OUTPUT | grep -o '"SecretAccessKey": "[^"]*"' | cut -d'"' -f4)
export AWS_SESSION_TOKEN=$(echo $ASSUME_ROLE_OUTPUT | grep -o '"SessionToken": "[^"]*"' | cut -d'"' -f4)
aws eks list-clusters | jq -r '.clusters[0]'
humoflife marked this conversation as resolved.
Show resolved Hide resolved
humoflife marked this conversation as resolved.
Show resolved Hide resolved
stdoutField: status.atFunction.shell.stdout
stderrField: status.atFunction.shell.stderr
11 changes: 11 additions & 0 deletions example/aws/extra-resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
humoflife marked this conversation as resolved.
Show resolved Hide resolved
metadata:
labels:
account: demo
name: demo
spec:
assumeRoleChain:
- roleARN: arn:aws:iam::00000002:role/Crossplane
humoflife marked this conversation as resolved.
Show resolved Hide resolved
credentials:
source: IRSA
18 changes: 18 additions & 0 deletions example/aws/functions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-shell
annotations:
# This tells crossplane beta render to connect to the function locally.
render.crossplane.io/runtime: Development
spec:
# This is ignored when using the Development runtime.
package: function-shell
---
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-extra-resources
spec:
package: xpkg.upbound.io/crossplane-contrib/function-extra-resources:v0.0.3
6 changes: 6 additions & 0 deletions example/aws/xr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: example.crossplane.io/v1
kind: XR
metadata:
name: example-aws
spec: {}
12 changes: 10 additions & 2 deletions fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1"
"github.com/crossplane/function-sdk-go/request"
"github.com/crossplane/function-sdk-go/response"

"github.com/keegancsmith/shell"
)

Expand Down Expand Up @@ -87,7 +86,16 @@ func (f *Function) RunFunction(_ context.Context, req *fnv1beta1.RunFunctionRequ

var shellEnvVars = make(map[string]string)
for _, envVar := range in.ShellEnvVars {
shellEnvVars[envVar.Key] = envVar.Value
if envVar.ValueRef != "" {
envValue, err := fromValueRef(req, envVar.ValueRef)
if err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot process contents of valueRef %s", envVar.ValueRef))
return rsp, nil
}
shellEnvVars[envVar.Key] = envValue
} else {
shellEnvVars[envVar.Key] = envVar.Value
}
}

if len(in.ShellEnvVarsRef.Keys) > 0 {
Expand Down
5 changes: 3 additions & 2 deletions input/v1alpha1/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ type Parameters struct {
}

type ShellEnvVar struct {
Key string `json:"key,omitempty"`
Value string `json:"value,omitempty"`
Key string `json:"key,omitempty"`
Value string `json:"value,omitempty"`
ValueRef string `json:"valueRef,omitempty"`
}

type ShellEnvVarsRef struct {
Expand Down
2 changes: 2 additions & 0 deletions package/input/template.fn.crossplane.io_parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ spec:
type: string
value:
type: string
valueRef:
type: string
type: object
type: array
shellEnvVarsRef:
Expand Down