Skip to content

Commit

Permalink
Merge pull request #77 from vladimirvivien/starlark-impl-parity
Browse files Browse the repository at this point in the history
Starlark - Implement Configuration Functions Impl
  • Loading branch information
vladimirvivien committed Jun 18, 2020
2 parents 896db9b + 90209bf commit c49ad1e
Show file tree
Hide file tree
Showing 9 changed files with 563 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/sirupsen/logrus v1.4.2
github.com/spf13/cobra v0.0.5
github.com/vladimirvivien/echo v0.0.1-alpha.4
go.starlark.net v0.0.0-20200615180055-61b64bc45990
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
Expand Down Expand Up @@ -153,6 +156,8 @@ github.com/vladimirvivien/echo v0.0.1-alpha.4 h1:0E0smrv0j/7uXBXunjDeFzPHJByUojT
github.com/vladimirvivien/echo v0.0.1-alpha.4/go.mod h1:64h/A7+5GmiBaeztyIr8BVf/07B7knV6OAP06jX+oyE=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20200615180055-61b64bc45990 h1:uDQRBsInkx8dnsM61qp8NPorEWHq2LBvVYiZK9ikCag=
go.starlark.net v0.0.0-20200615180055-61b64bc45990/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down Expand Up @@ -197,6 +202,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
44 changes: 44 additions & 0 deletions starlark/crashd_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"go.starlark.net/starlark"
)

// addDefaultCrashdConf initalizes a Starlark Dict with default
// crashd_config configuration data
func addDefaultCrashdConf(thread *starlark.Thread) error {
args := []starlark.Tuple{
starlark.Tuple{starlark.String("gid"), starlark.String(getGid())},
starlark.Tuple{starlark.String("uid"), starlark.String(getUid())},
starlark.Tuple{starlark.String("workdir"), starlark.String(defaults.workdir)},
starlark.Tuple{starlark.String("output_path"), starlark.String(defaults.outPath)},
}

_, err := crashdConfigFn(thread, nil, nil, args)
if err != nil {
return err
}

return nil
}

// crashConfig is built-in starlark function that wraps the kwargs into a dictionary value.
// The result is also added to the thread for other built-in to access.
func crashdConfigFn(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var dictionary *starlark.Dict
if kwargs != nil {
dict, err := tupleSliceToDict(kwargs)
if err != nil {
return starlark.None, err
}
dictionary = dict
}

// save dict to be used as default
thread.SetLocal(identifiers.crashdCfg, dictionary)

return dictionary, nil
}
133 changes: 133 additions & 0 deletions starlark/crashd_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"strings"
"testing"

"go.starlark.net/starlark"
)

func TestCrashdConfigNew(t *testing.T) {
e := New()
if e.thread == nil {
t.Error("thread is nil")
}
cfg := e.thread.Local(identifiers.crashdCfg)
if cfg == nil {
t.Error("crashd_config dict not found in thread")
}
}

func TestCrashdConfigFunc(t *testing.T) {
tests := []struct {
name string
script string
eval func(t *testing.T, script string)
}{
{
name: "crash_config saved in thread",
script: `crashd_config(foo="fooval", bar="barval")`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.thread.Local(identifiers.crashdCfg)
if data == nil {
t.Fatal("crashd_config not saved in thread local")
}
cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key configs.crashd: %T", data)
}
if cfg.Len() != 2 {
t.Fatalf("unexpected item count in configs.crashd: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("foo"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'foo' not found in configs.crashd")
}
if trimQuotes(val.String()) != "fooval" {
t.Fatalf("unexpected value for key 'foo': %s", val.String())
}
},
},

{
name: "crash_config returned value",
script: `cfg = crashd_config(foo="fooval", bar="barval")`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.result["cfg"]
if data == nil {
t.Fatal("crashd_config function not returning value")
}
cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key configs.crashd: %T", data)
}
if cfg.Len() != 2 {
t.Fatalf("unexpected item count in configs.crashd: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("foo"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'foo' not found in configs.crashd")
}
if trimQuotes(val.String()) != "fooval" {
t.Fatalf("unexpected value for key %s in configs.crashd", val.String())
}
},
},

{
name: "crash_config default",
script: `one = 1`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.thread.Local(identifiers.crashdCfg)
if data == nil {
t.Fatal("default crashd_config not saved in thread local")
}

cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key crashd_config: %T", data)
}
if cfg.Len() != 4 {
t.Fatalf("unexpected item count in configs.crashd: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("uid"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'foo' not found in configs.crashd")
}
if trimQuotes(val.String()) != getUid() {
t.Fatalf("unexpected value for key %s in configs.crashd", val.String())
}
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.eval(t, test.script)
})
}
}
45 changes: 45 additions & 0 deletions starlark/ssh_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"go.starlark.net/starlark"
)

// addDefaultSshConf initalizes a Starlark Dict with default
// ssh_config configuration data
func addDefaultSSHConf(thread *starlark.Thread) error {
args := []starlark.Tuple{
starlark.Tuple{starlark.String("username"), starlark.String(getUsername())},
starlark.Tuple{starlark.String("private_key_path"), starlark.String(defaults.pkPath)},
starlark.Tuple{starlark.String("conn_retries"), starlark.MakeInt(defaults.connRetries)},
starlark.Tuple{starlark.String("conn_timeout"), starlark.MakeInt(defaults.connTimeout)},
}

_, err := sshConfigFn(thread, nil, nil, args)
if err != nil {
return err
}

return nil
}

// sshConfigFn is the backing built-in function for the `ssh_config` configuration function.
// It creates and returns a dictionary from collected configs (as kwargs)
// It also saves the dict into the thread as the last known ssh config to be used as default.
func sshConfigFn(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var dictionary *starlark.Dict
if kwargs != nil {
dict, err := tupleSliceToDict(kwargs)
if err != nil {
return starlark.None, err
}
dictionary = dict
}

// save to be used as default when needed
thread.SetLocal(identifiers.sshCfg, dictionary)

return dictionary, nil
}
134 changes: 134 additions & 0 deletions starlark/ssh_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"strings"
"testing"

"go.starlark.net/starlark"
)

func TestSSHConfigNew(t *testing.T) {
e := New()
if e.thread == nil {
t.Error("thread is nil")
}
cfg := e.thread.Local(identifiers.sshCfg)
if cfg == nil {
t.Error("ssh_config dict not found in thread")
}
}

func TestSSHConfigFunc(t *testing.T) {
tests := []struct {
name string
script string
eval func(t *testing.T, script string)
}{
{
name: "ssh_config saved in thread",
script: `ssh_config(username="uname", private_key_path="path")`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.thread.Local(identifiers.sshCfg)
if data == nil {
t.Fatal("ssh_config not saved in thread local")
}
cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key ssh_config: %T", data)
}
if cfg.Len() != 2 {
t.Fatalf("unexpected item count in ssh_config: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("username"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'username' not found in ssh_config")
}
if trimQuotes(val.String()) != "uname" {
t.Fatalf("unexpected value for key 'foo': %s", val.String())
}
},
},

{
name: "ssh_config returned value",
script: `cfg = ssh_config(username="uname", private_key_path="path")`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.result["cfg"]
if data == nil {
t.Fatal("ssh_config function not returning value")
}
cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key ssh_config: %T", data)
}
if cfg.Len() != 2 {
t.Fatalf("unexpected item count in ssh_config: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("private_key_path"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'private_key_path' not found in ssh_config")
}
if trimQuotes(val.String()) != "path" {
t.Fatalf("unexpected value for key %s in ssh_config", val.String())
}
},
},

{
name: "crash_config default",
script: `one = 1`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}
data := exe.thread.Local(identifiers.sshCfg)
if data == nil {
t.Fatal("default ssh_config not saved in thread local")
}

cfg, ok := data.(*starlark.Dict)
if !ok {
t.Fatalf("unexpected type for thread local key ssh_config: %T", data)
}
if cfg.Len() != 4 {
t.Fatalf("unexpected item count in ssh_config: %d", cfg.Len())
}
val, found, err := cfg.Get(starlark.String("conn_retries"))
if err != nil {
t.Fatal(err)
}
if !found {
t.Fatalf("key 'conn_retries' not found in ssh_config")
}
retries := val.(starlark.Int)
if retries.BigInt().Int64() != int64(10) {
t.Fatalf("unexpected value for key %s in configs.crashd", val.String())
}
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.eval(t, test.script)
})
}
}

0 comments on commit c49ad1e

Please sign in to comment.