Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemenation of host_list_provider function.
See documentation for detail on the notion of providers. Signed-off-by: Vladimir Vivien <vivienv@vmware.com>
- Loading branch information
1 parent
c49ad1e
commit daf30cb
Showing
8 changed files
with
277 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) 2020 VMware, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package starlark | ||
|
||
import ( | ||
"fmt" | ||
|
||
"go.starlark.net/starlark" | ||
"go.starlark.net/starlarkstruct" | ||
) | ||
|
||
// hostListProvider is a built-in starlark function that collects compute resources as a list of host IPs | ||
// Starlark format: host_list_provider(hosts=<host-list> [, ssh_config=ssh_config()]) | ||
func hostListProvider(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { | ||
var dictionary starlark.StringDict | ||
if kwargs != nil { | ||
dict, err := kwargsToStringDict(kwargs) | ||
if err != nil { | ||
return starlark.None, err | ||
} | ||
dictionary = dict | ||
} | ||
|
||
return newHostListProvider(thread, dictionary) | ||
} | ||
|
||
// newHostListProvider returns a struct with host list provider info | ||
func newHostListProvider(thread *starlark.Thread, dictionary starlark.StringDict) (*starlarkstruct.Struct, error) { | ||
// validate args | ||
if _, ok := dictionary["hosts"]; !ok { | ||
return nil, fmt.Errorf("%s: missing hosts argument", identifiers.hostListProvider) | ||
} | ||
|
||
// augment args | ||
dictionary["kind"] = starlark.String(identifiers.hostListProvider) | ||
dictionary["transport"] = starlark.String("ssh") | ||
if _, ok := dictionary[identifiers.sshCfg]; !ok { | ||
data := thread.Local(identifiers.sshCfg) | ||
sshcfg, ok := data.(starlark.StringDict) | ||
if !ok { | ||
return nil, fmt.Errorf("%s: default ssh_config not found", identifiers.hostListProvider) | ||
} | ||
dictionary[identifiers.sshCfg] = starlarkstruct.FromStringDict(starlarkstruct.Default, sshcfg) | ||
} | ||
|
||
return starlarkstruct.FromStringDict(starlarkstruct.Default, dictionary), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) 2020 VMware, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package starlark | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"go.starlark.net/starlark" | ||
"go.starlark.net/starlarkstruct" | ||
) | ||
|
||
func TestHostListProvider(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
script string | ||
eval func(t *testing.T, script string) | ||
}{ | ||
{ | ||
name: "single host", | ||
script: `provider = host_list_provider(hosts="foo.host")`, | ||
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["provider"] | ||
if data == nil { | ||
t.Fatalf("%s function not returning value", identifiers.hostListProvider) | ||
} | ||
provider, ok := data.(*starlarkstruct.Struct) | ||
if !ok { | ||
t.Fatalf("expecting *starlark.Struct, got %T", data) | ||
} | ||
if len(provider.AttrNames()) != 1 { | ||
t.Fatalf("unexpected item count in configs.crashd: %d", len(provider.AttrNames())) | ||
} | ||
val, err := provider.Attr("hosts") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if trimQuotes(val.String()) != "foo.host" { | ||
t.Fatalf("unexpected value for key %s in configs.crashd", val.String()) | ||
} | ||
}, | ||
}, | ||
{ | ||
name: "multiple hosts", | ||
script: `provider = host_list_provider(hosts=["foo.host.1", "foo.host.2"])`, | ||
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["provider"] | ||
if data == nil { | ||
t.Fatalf("%s function not returning value", identifiers.hostListProvider) | ||
} | ||
provider, ok := data.(*starlarkstruct.Struct) | ||
if !ok { | ||
t.Fatalf("expecting *starlark.Struct, got %T", data) | ||
} | ||
if len(provider.AttrNames()) != 1 { | ||
t.Fatalf("unexpected item %s: %d", identifiers.hostListProvider, len(provider.AttrNames())) | ||
} | ||
val, err := provider.Attr("hosts") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
list := val.(*starlark.List) | ||
if list.Len() != 2 { | ||
t.Fatalf("expecting %d items for argument 'hosts', got %d", 2, list.Len()) | ||
} | ||
}, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
test.eval(t, test.script) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) 2020 VMware, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package starlark | ||
|
||
import ( | ||
"fmt" | ||
|
||
"go.starlark.net/starlark" | ||
"go.starlark.net/starlarkstruct" | ||
) | ||
|
||
// resourcesFunc is a built-in starlark function that prepares returns compute resources as a struct. | ||
// Starlark format: resources(provider=<provider-function>) | ||
func resourcesFunc(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { | ||
var dictionary starlark.StringDict | ||
if kwargs != nil { | ||
dict, err := kwargsToStringDict(kwargs) | ||
if err != nil { | ||
return starlark.None, err | ||
} | ||
dictionary = dict | ||
} | ||
|
||
var provider *starlarkstruct.Struct | ||
if hosts, ok := dictionary["hosts"]; ok { | ||
prov, err := newHostListProvider(thread, starlark.StringDict{"hosts": hosts}) | ||
if err != nil { | ||
return starlark.None, err | ||
} | ||
provider = prov | ||
} else if prov, ok := dictionary["provider"]; ok { | ||
provider = prov.(*starlarkstruct.Struct) | ||
} | ||
|
||
// enumerates resources | ||
return enum(provider) | ||
} | ||
|
||
// enum returns a struct containing the fully enumerated compute resource | ||
// info needed to execute commands. | ||
func enum(provider *starlarkstruct.Struct) (*starlarkstruct.Struct, error) { | ||
if provider == nil { | ||
fmt.Errorf("missing provider") | ||
} | ||
|
||
var resStruct *starlarkstruct.Struct | ||
|
||
kindVal, err := provider.Attr("kind") | ||
if err != nil { | ||
return nil, fmt.Errorf("provider missing field kind") | ||
} | ||
|
||
kind := trimQuotes(kindVal.String()) | ||
|
||
switch kind { | ||
case identifiers.hostListProvider: | ||
names, err := provider.Attr("hosts") | ||
if err != nil { | ||
return nil, fmt.Errorf("hosts not found in %s", identifiers.hostListProvider) | ||
} | ||
transport, err := provider.Attr("transport") | ||
if err != nil { | ||
return nil, fmt.Errorf("transport not found in %s", identifiers.hostListProvider) | ||
} | ||
|
||
sshCfg, err := provider.Attr(identifiers.sshCfg) | ||
if err != nil { | ||
return nil, fmt.Errorf("ssh_config not found in %s", identifiers.hostListProvider) | ||
} | ||
|
||
dict := starlark.StringDict{ | ||
"kind": starlark.String("host_list_resources"), | ||
"names": names, | ||
"ip_addresses": names, | ||
"transport": transport, | ||
"ssh_config": sshCfg, | ||
} | ||
resStruct = starlarkstruct.FromStringDict(starlarkstruct.Default, dict) | ||
} | ||
return resStruct, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.