Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
Reference secrets by app-name.secret-name
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuildthecloud committed Jun 28, 2022
1 parent e47126a commit 6d8f464
Show file tree
Hide file tree
Showing 29 changed files with 639 additions and 868 deletions.
1 change: 1 addition & 0 deletions docs/docs/100-Reference/01-command-line/acorn_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ acorn images
### Options

```
-a, --all Include untagged images
-h, --help help for image
--no-trunc Don't truncate IDs
-o, --output string Output format (json, yaml, {{gotemplate}})
Expand Down
70 changes: 57 additions & 13 deletions integration/client/secrets/secrets_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,58 @@
package secrets

import (
"context"
"testing"

"github.com/acorn-io/acorn/integration/helper"
apiv1 "github.com/acorn-io/acorn/pkg/apis/api.acorn.io/v1"
v1 "github.com/acorn-io/acorn/pkg/apis/internal.acorn.io/v1"
"github.com/acorn-io/acorn/pkg/build"
"github.com/acorn-io/acorn/pkg/client"
kclient "github.com/acorn-io/acorn/pkg/k8sclient"
"github.com/acorn-io/baaah/pkg/router"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
)

func TestSecretCrossbinding(t *testing.T) {
ctx := context.Background()
kclient := helper.MustReturn(kclient.Default)
c, _ := helper.ClientAndNamespace(t)

image, err := build.Build(ctx, "../testdata/secrets/acorn.cue", &build.Options{
Client: c,
Cwd: "../testdata/secrets",
})
if err != nil {
t.Fatal(err)
}

app, err := c.AppRun(ctx, image.ID, nil)
if err != nil {
t.Fatal(err)
}

app = helper.WaitForObject(t, c.GetClient().Watch, &apiv1.AppList{}, app, func(app *apiv1.App) bool {
return app.Status.Ready
})

secondApp := &v1.AppInstance{}
err = kclient.Get(ctx, router.Key(app.Status.Namespace, "second"), secondApp)
if err != nil {
t.Fatal(err)
}

secret := &corev1.Secret{}
err = kclient.Get(ctx, router.Key(secondApp.Status.Namespace, "second"), secret)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, "true", string(secret.Data["parent"]))

}

func TestSecretCreate(t *testing.T) {
restConfig := helper.StartAPI(t)

Expand All @@ -21,7 +65,7 @@ func TestSecretCreate(t *testing.T) {
t.Fatal(err)
}

secret, err := c.SecretCreate(ctx, "foo", "secretType", map[string][]byte{
secret, err := c.SecretCreate(ctx, "foo", "opaque", map[string][]byte{
"key1": []byte("value1"),
"key2": []byte("value2"),
})
Expand All @@ -30,7 +74,7 @@ func TestSecretCreate(t *testing.T) {
}

assert.Equal(t, "foo", secret.Name)
assert.Equal(t, "secretType", secret.Type)
assert.Equal(t, "opaque", secret.Type)
assert.Len(t, secret.Data, 0)
assert.Len(t, secret.Keys, 2)
assert.Equal(t, "key1", secret.Keys[0])
Expand All @@ -50,12 +94,12 @@ func TestSecretList(t *testing.T) {
t.Fatal(err)
}

secret1, err := c.SecretCreate(ctx, "secret1", "type1", map[string][]byte{"key": []byte("value")})
secret1, err := c.SecretCreate(ctx, "secret1", "opaque", map[string][]byte{"key": []byte("value")})
if err != nil {
t.Fatal(err)
}

secret2, err := c.SecretCreate(ctx, "secret2", "type2", map[string][]byte{"key2": []byte("value2")})
secret2, err := c.SecretCreate(ctx, "secret2", "opaque", map[string][]byte{"key2": []byte("value2")})
if err != nil {
t.Fatal(err)
}
Expand All @@ -82,12 +126,12 @@ func TestSecretGet(t *testing.T) {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret1", "type1", map[string][]byte{"key": []byte("value")})
_, err = c.SecretCreate(ctx, "secret1", "opaque", map[string][]byte{"key": []byte("value")})
if err != nil {
t.Fatal(err)
}

secret, err := c.SecretCreate(ctx, "secret2", "type2", map[string][]byte{"key2": []byte("value2")})
secret, err := c.SecretCreate(ctx, "secret2", "opaque", map[string][]byte{"key2": []byte("value2")})
if err != nil {
t.Fatal(err)
}
Expand All @@ -113,12 +157,12 @@ func TestSecretExpose(t *testing.T) {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret1", "type1", map[string][]byte{"key": []byte("value")})
_, err = c.SecretCreate(ctx, "secret1", "opaque", map[string][]byte{"key": []byte("value")})
if err != nil {
t.Fatal(err)
}

secret, err := c.SecretCreate(ctx, "secret2", "type2", map[string][]byte{"key2": []byte("value2")})
secret, err := c.SecretCreate(ctx, "secret2", "opaque", map[string][]byte{"key2": []byte("value2")})
if err != nil {
t.Fatal(err)
}
Expand All @@ -145,12 +189,12 @@ func TestSecretUpdate(t *testing.T) {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret1", "type1", map[string][]byte{"key": []byte("value")})
_, err = c.SecretCreate(ctx, "secret1", "opaque", map[string][]byte{"key": []byte("value")})
if err != nil {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret2", "type2", map[string][]byte{"key2": []byte("value2")})
_, err = c.SecretCreate(ctx, "secret2", "opaque", map[string][]byte{"key2": []byte("value2")})
if err != nil {
t.Fatal(err)
}
Expand All @@ -166,7 +210,7 @@ func TestSecretUpdate(t *testing.T) {
}

assert.Equal(t, "secret2", secretNewNew.Name)
assert.Equal(t, "type2", secretNewNew.Type)
assert.Equal(t, "opaque", secretNewNew.Type)
assert.Len(t, secretNewNew.Data, 0)
assert.Equal(t, []string{"key3"}, secretNewNew.Keys)
assert.Equal(t, secretNew, secretNewNew)
Expand All @@ -185,12 +229,12 @@ func TestSecretDelete(t *testing.T) {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret1", "type1", map[string][]byte{"key": []byte("value")})
_, err = c.SecretCreate(ctx, "secret1", "opaque", map[string][]byte{"key": []byte("value")})
if err != nil {
t.Fatal(err)
}

_, err = c.SecretCreate(ctx, "secret2", "type2", map[string][]byte{"key2": []byte("value2")})
_, err = c.SecretCreate(ctx, "secret2", "opaque", map[string][]byte{"key2": []byte("value2")})
if err != nil {
t.Fatal(err)
}
Expand Down
22 changes: 22 additions & 0 deletions integration/client/testdata/secrets/acorn.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
acorns: {
first: {
build: {
acornfile: "first.cue"
}
secrets: [
"parent:first"
]
}
second: {
build: {
acornfile: "second.cue"
}
secrets: [
"first.first:second"
]
}
}

secrets: parent: {
data: parent: "true"
}
5 changes: 5 additions & 0 deletions integration/client/testdata/secrets/first.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
secrets: first: {
data: {
key: "first-value"
}
}
5 changes: 5 additions & 0 deletions integration/client/testdata/secrets/second.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
secrets: second: {
data: {
key: "second-value"
}
}
74 changes: 29 additions & 45 deletions integration/secrets/secret_test.go
Original file line number Diff line number Diff line change
@@ -1,107 +1,91 @@
package run

import (
"context"
"testing"

"github.com/acorn-io/acorn/integration/helper"
apiv1 "github.com/acorn-io/acorn/pkg/apis/api.acorn.io/v1"
v1 "github.com/acorn-io/acorn/pkg/apis/internal.acorn.io/v1"
"github.com/acorn-io/acorn/pkg/build"
hclient "github.com/acorn-io/acorn/pkg/k8sclient"
"github.com/acorn-io/acorn/pkg/labels"
"github.com/acorn-io/acorn/pkg/k8sclient"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestText(t *testing.T) {
helper.StartController(t)

ctx := helper.GetCTX(t)
client := helper.MustReturn(hclient.Default)
ns := helper.TempNamespace(t, client)

c, _ := helper.ClientAndNamespace(t)
kclient := helper.MustReturn(k8sclient.Default)
image, err := build.Build(helper.GetCTX(t), "./testdata/generated/acorn.cue", &build.Options{
Client: helper.BuilderClient(t, ns.Name),
Client: c,
Cwd: "./testdata/generated",
})
if err != nil {
t.Fatal(err)
}

appInstance := &v1.AppInstance{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "simple-app",
Namespace: ns.Name,
Labels: map[string]string{
labels.AcornRootNamespace: ns.Name,
},
},
Spec: v1.AppInstanceSpec{
Image: image.ID,
},
}

err = client.Create(ctx, appInstance)
app, err := c.AppRun(context.Background(), image.ID, nil)
if err != nil {
t.Fatal(err)
}

appInstance = helper.WaitForObject(t, client.Watch, &v1.AppInstanceList{}, appInstance, func(obj *v1.AppInstance) bool {
app = helper.WaitForObject(t, c.GetClient().Watch, &apiv1.AppList{}, app, func(obj *apiv1.App) bool {
return obj.Status.Namespace != ""
})

for _, secretName := range []string{"gen", "gen2"} {
secret := helper.Wait(t, client.Watch, &corev1.SecretList{}, func(obj *corev1.Secret) bool {
return obj.Namespace == appInstance.Status.Namespace &&
secret := helper.Wait(t, kclient.Watch, &corev1.SecretList{}, func(obj *corev1.Secret) bool {
return obj.Namespace == app.Status.Namespace &&
obj.Name == secretName && len(obj.Data) > 0
})
assert.Equal(t, "static", string(secret.Data["content"]))
}

_, err = c.SecretGet(context.Background(), app.Name+".gen")
if err != nil {
t.Fatal(err)
}

gen2, err := c.SecretExpose(context.Background(), app.Name+".gen2")
if err != nil {
t.Fatal(err)
}

assert.Equal(t, "static", string(gen2.Data["content"]))
}

func TestJSON(t *testing.T) {
helper.StartController(t)

ctx := helper.GetCTX(t)
client := helper.MustReturn(hclient.Default)
ns := helper.TempNamespace(t, client)
c, _ := helper.ClientAndNamespace(t)
client := helper.MustReturn(k8sclient.Default)

image, err := build.Build(helper.GetCTX(t), "./testdata/generated-json/acorn.cue", &build.Options{
Client: helper.BuilderClient(t, ns.Name),
Client: c,
Cwd: "./testdata/generated-json",
})
if err != nil {
t.Fatal(err)
}

appInstance := &v1.AppInstance{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "simple-app",
Namespace: ns.Name,
Labels: map[string]string{
labels.AcornRootNamespace: ns.Name,
},
},
Spec: v1.AppInstanceSpec{
Image: image.ID,
},
}

err = client.Create(ctx, appInstance)
app, err := c.AppRun(ctx, image.ID, nil)
if err != nil {
t.Fatal(err)
}

appInstance = helper.WaitForObject(t, client.Watch, &v1.AppInstanceList{}, appInstance, func(obj *v1.AppInstance) bool {
app = helper.WaitForObject(t, c.GetClient().Watch, &apiv1.AppList{}, app, func(obj *apiv1.App) bool {
return obj.Status.Namespace != ""
})

for _, secretName := range []string{"gen", "gen2"} {
secret := helper.Wait(t, client.Watch, &corev1.SecretList{}, func(obj *corev1.Secret) bool {
return obj.Namespace == appInstance.Status.Namespace &&
return obj.Namespace == app.Status.Namespace &&
obj.Name == secretName && len(obj.Data) > 0
})
assert.Equal(t, corev1.SecretType("other"), secret.Type)
assert.Equal(t, corev1.SecretType(v1.SecretTypePrefix+"basic"), secret.Type)
assert.Equal(t, "value", string(secret.Data["key"]))
assert.Equal(t, "static", string(secret.Data["pass"]))
}
Expand Down
6 changes: 3 additions & 3 deletions integration/secrets/testdata/generated-json/acorn.cue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ jobs: {
#!/bin/sh
cat << EOF > /run/secrets/output
{
"type": "other",
"type": "basic",
"data": {
"key": "value",
"pass": "$PASS"
"key": "$(echo -n value | base64)",
"pass": "$(echo -n $PASS | base64)"
}
}
EOF
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/internal.acorn.io/v1/appinstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ var (
AppInstanceConditionSecrets = "secrets"
AppInstanceConditionContainers = "containers"
AppInstanceConditionJobs = "jobs"
AppInstanceConditionAcorns = "acorns"
AppInstanceConditionReady = "Ready"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down Expand Up @@ -104,6 +106,8 @@ type AppInstanceStatus struct {
Columns AppColumns `json:"columns,omitempty"`
ContainerStatus map[string]ContainerStatus `json:"containerStatus,omitempty"`
JobsStatus map[string]JobStatus `json:"jobsStatus,omitempty"`
AcornStatus map[string]AcornStatus `json:"acornStatus,omitempty"`
Ready bool `json:"ready,omitempty"`
Stopped bool `json:"stopped,omitempty"`
Namespace string `json:"namespace,omitempty"`
AppImage AppImage `json:"appImage,omitempty"`
Expand All @@ -112,6 +116,14 @@ type AppInstanceStatus struct {
Endpoints []Endpoint `json:"endpoints,omitempty"`
}

type AcornStatus struct {
ContainerStatus map[string]ContainerStatus `json:"containerStatus,omitempty"`
JobsStatus map[string]JobStatus `json:"jobsStatus,omitempty"`
AcornStatus map[string]AcornStatus `json:"acornStatus,omitempty"`
Stopped bool `json:"stopped,omitempty"`
Ready bool `json:"ready,omitempty"`
}

type Endpoint struct {
Target string `json:"target,omitempty"`
TargetPort int32 `json:"targetPort,omitempty"`
Expand Down

0 comments on commit 6d8f464

Please sign in to comment.