Skip to content

Commit

Permalink
feat(cdk): life cycle event 'cdk-init'
Browse files Browse the repository at this point in the history
Signed-off-by: Salim Afiune Maya <[email protected]>
  • Loading branch information
afiune committed Jul 6, 2022
1 parent 99aacd8 commit 12eee01
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 17 deletions.
12 changes: 12 additions & 0 deletions cli/cmd/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@ func runComponentsInstall(_ *cobra.Command, args []string) (err error) {
return
}

cli.StartProgress(fmt.Sprintf("Configuring component %s...", component.Name))

// component life cycle: initialize
stdout, stderr, errCmd := component.RunAndReturn([]string{"cdk-init"}, nil, cli.envs()...)
if errCmd != nil {
cli.Log.Warnw("component life cycle",
"error", errCmd.Error(), "stdout", stdout, "stderr", stderr)
} else {
cli.Log.Infow("component life cycle", "stdout", stdout, "stderr", stderr)
}

cli.StopProgress()
cli.OutputHuman("The component %s was installed.\n", args[0])
return
}
Expand Down
52 changes: 41 additions & 11 deletions lwcomponent/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ var (
helloWorld []byte
//go:embed test_resources/hello-world2.sig
helloWorldSig string
//go:embed test_resources/env-vars.sh
envVars []byte
//go:embed test_resources/env-vars.sig
envVarsSig string
)

func ensureMockComponent(version, signature string) (string, error) {
func ensureMockComponent(version, content, signature string) (string, error) {
cPath, err := mockComponent.Path()
if err.Error() != "component not found on disk" {
return "", err
Expand All @@ -79,11 +83,11 @@ func ensureMockComponent(version, signature string) (string, error) {
}
}

return cPath, os.WriteFile(cPath, helloWorld, 0744)
return cPath, os.WriteFile(cPath, []byte(content), 0744)
}

func TestGetComponent(t *testing.T) {
componentDir, err := ensureMockComponent("", "")
componentDir, err := ensureMockComponent("", "", "")
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
Expand Down Expand Up @@ -158,7 +162,7 @@ var currentVersionTests = []currentVersionTest{
func TestCurrentVersion(t *testing.T) {
for _, cvt := range currentVersionTests {
t.Run(cvt.Name, func(t *testing.T) {
componentDir, err := ensureMockComponent(cvt.Version, "")
componentDir, err := ensureMockComponent(cvt.Version, "", "")
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
Expand Down Expand Up @@ -208,7 +212,7 @@ var currentSignatureTests = []currentSignatureTest{
func TestCurrentSignature(t *testing.T) {
for _, cst := range currentSignatureTests {
t.Run(cst.Name, func(t *testing.T) {
componentDir, err := ensureMockComponent("", cst.Signature)
componentDir, err := ensureMockComponent("", string(helloWorld), cst.Signature)
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
Expand Down Expand Up @@ -253,7 +257,7 @@ var updateAvailableTests = []updateAvailableTest{
func TestUpdateAvailable(t *testing.T) {
for _, uat := range updateAvailableTests {
t.Run(uat.Name, func(t *testing.T) {
componentDir, err := ensureMockComponent(uat.Version, "")
componentDir, err := ensureMockComponent(uat.Version, "", "")
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
Expand All @@ -267,7 +271,7 @@ func TestUpdateAvailable(t *testing.T) {
}

func TestComponentStatus(t *testing.T) {
componentDir, err := ensureMockComponent("", "")
componentDir, err := ensureMockComponent("", "", "")
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
Expand All @@ -281,38 +285,51 @@ type RunAndReturnTest struct {
Name string
Component lwcomponent.Component
Version string
Content string
Signature string
Args []string
Stdin io.Reader
ExpectedStdout string
ExpectedStderr string
Error error
Envs []string
}

var RunAndReturnTests = []RunAndReturnTest{
RunAndReturnTest{
Name: "OK",
Component: mockComponent,
Version: "1.0.0",
Content: string(helloWorld),
Signature: helloWorldSig,
Args: []string{"World"},
Stdin: strings.NewReader("Error"),
ExpectedStdout: "Hello World!\n",
ExpectedStderr: "Hello Error!\n",
Error: nil,
},
RunAndReturnTest{
Name: "env-vars",
Component: mockComponent,
Version: "1.0.0",
Content: string(envVars),
Signature: envVarsSig,
Args: []string{"cdk-init"},
ExpectedStdout: "Hello from the environment!\n",
Envs: []string{"LW_TEST=from the environment"},
},
}

func TestRunAndReturn(t *testing.T) {
for _, rart := range RunAndReturnTests {
t.Run(rart.Name, func(t *testing.T) {
componentDir, err := ensureMockComponent(rart.Version, rart.Signature)
componentDir, err := ensureMockComponent(rart.Version, rart.Content, rart.Signature)
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
defer os.RemoveAll(componentDir)

actualStdout, actualStderr, actualError := rart.Component.RunAndReturn(rart.Args, rart.Stdin)
actualStdout, actualStderr, actualError := rart.Component.RunAndReturn(rart.Args, rart.Stdin, rart.Envs...)

if rart.Error != nil {
assert.Equal(t, rart.Error.Error(), actualError.Error())
Expand All @@ -329,38 +346,51 @@ type RunAndOutputTest struct {
Name string
Component lwcomponent.Component
Version string
Content string
Signature string
Args []string
Stdin io.Reader
Expected string
Error error
Envs []string
}

var RunAndOutputTests = []RunAndOutputTest{
RunAndOutputTest{
Name: "OK",
Component: mockComponent,
Version: "1.0.0",
Content: string(helloWorld),
Signature: helloWorldSig,
Args: []string{"World"},
Stdin: strings.NewReader("Error"),
Expected: "Hello World!\nHello !\n",
Error: nil,
},
RunAndOutputTest{
Name: "env-vars",
Component: mockComponent,
Version: "1.0.0",
Content: string(envVars),
Signature: envVarsSig,
Args: []string{"cdk-init"},
Expected: "Hello environment test!\n",
Envs: []string{"LW_TEST=environment test"},
},
}

func TestRunAndOutput(t *testing.T) {
for _, raot := range RunAndOutputTests {
t.Run(raot.Name, func(t *testing.T) {
componentDir, err := ensureMockComponent(raot.Version, raot.Signature)
componentDir, err := ensureMockComponent(raot.Version, raot.Content, raot.Signature)
if err != nil {
assert.FailNow(t, "Unable to ensureMockComponent")
}
defer os.RemoveAll(componentDir)

actual := capturer.CaptureOutput(func() {
// @afiune fake STDIN
actualError := raot.Component.RunAndOutput(raot.Args)
actualError := raot.Component.RunAndOutput(raot.Args, raot.Envs...)

if raot.Error != nil {
assert.Equal(t, raot.Error.Error(), actualError.Error())
Expand Down
10 changes: 4 additions & 6 deletions lwcomponent/executable.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ func (c Component) RunAndOutput(args []string, envs ...string) error {
return c.run(cmd)
}

// RunAndReturn runs the command and returns its standard output and standard error
func (c Component) RunAndReturn(args []string, stdin io.Reader) (
// RunAndReturn runs the command and returns its standard output and standard error,
// the provided environment variables will be accessible by the component
func (c Component) RunAndReturn(args []string, stdin io.Reader, envs ...string) (
stdout string,
stderr string,
err error,
Expand All @@ -61,10 +62,7 @@ func (c Component) RunAndReturn(args []string, stdin io.Reader) (

cmd := exec.Command(loc, args...)
cmd.Env = os.Environ()
// @afiune a number of components might need to have access to the Lacework API
// we need to figure out a way to pass credentials to the component
// cmd.Env = append(cmd.Env, fmt.Sprintf("LW_ACCOUNT=%s", account))
// cmd.Env = append(cmd.Env, fmt.Sprintf("LW_TOKEN=%s", token))
cmd.Env = append(cmd.Env, envs...)
cmd.Stdin = stdin
cmd.Stdout = &outBuff
cmd.Stderr = &errBuff
Expand Down
2 changes: 2 additions & 0 deletions lwcomponent/test_resources/env-vars.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
echo "Hello ${LW_TEST}!"
1 change: 1 addition & 0 deletions lwcomponent/test_resources/env-vars.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dW50cnVzdGVkIGNvbW1lbnQ6IApSV1FueUhuVEt6MVJpVktIRE5vR1A3amlNZEJ1WktUWEJLRUZpVFBBRTFidVFVQVlJbUthd1RiWVg4dU1GYXJOc2hQMThVZElySGRhTmxkSE1QeEsxMUsrUEpNdUtoWVE0UTA9CnRydXN0ZWQgY29tbWVudDogMS5SV1FueUhuVEt6MVJpZHFNbDQ1T3U1WGJKQ3JvVjd6b2hFMWpwYmlnVFVHWHlRWTk0QUY1dW80di4xLmRXNTBjblZ6ZEdWa0lHTnZiVzFsYm5RNklBcFNWMVJqYlZsamRqbFFNSGxOY0V4eVZuQTNWM2xJZG14MlJVMDJWbGhKYkZoelVHRTBRVlpWTDFNcmFIbHdVQ3RRZEhCRldFVnZjazVNUzNaUmVUSlNWMFF4VG1OS056TmxVMU5NWVVFMlRucExObkJ2Y3pscGIyUmhiRU5NY3poT1p6ZzlDblJ5ZFhOMFpXUWdZMjl0YldWdWREb2dDbTFpTW1wSlJWWkJVVE5QWmxJdkwwcFJjalV4VnpkUVIzRnJXRGhHYldNMVlVRktjQ3QwUTNKWE9IWm1XbVo2WW5WTU0yWnZlamR0UW1WNk1IcFFkbEJsZG1ReFUwRnJVa2xtU1cxRU1rZGpTa1ZsVUVKM1BUMD0Ka3BoUVlieFp2UUw0cEJzYTdtRVZWMXZwRUYzU0dXWmEvK29UdUN3TEFxRmVwai9ISzFibmJCdlFGY010Vy9STVJKU2lxSFV6TWwwa0ROcXJoSjBqQkE9PQ==

0 comments on commit 12eee01

Please sign in to comment.