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

Remove fields from outputs #85

Merged
merged 1 commit into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions action/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func setOutputsOnClaim(claim *claim.Claim, outputs map[string]string) error {
return nil
}

for outputName, v := range claim.Bundle.Outputs.Fields {
for outputName, v := range claim.Bundle.Outputs {
name := v.Definition
if name == "" {
return fmt.Errorf("invalid bundle: no definition set for output %q", outputName)
Expand Down Expand Up @@ -223,7 +223,7 @@ func opFromClaim(action string, stateless bool, c *claim.Claim, ii bundle.Invoca

var outputs []string
if c.Bundle.Outputs != nil {
for _, v := range c.Bundle.Outputs.Fields {
for _, v := range c.Bundle.Outputs {
outputs = append(outputs, v.Path)
}
}
Expand Down
64 changes: 31 additions & 33 deletions action/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,10 @@ func mockBundle() *bundle.Bundle {
Type: []interface{}{"string", "boolean"},
},
},
Outputs: &bundle.OutputsDefinition{
Fields: map[string]bundle.OutputDefinition{
"some-output": {
Path: "/tmp/some/path",
Definition: "ParamOne",
},
Outputs: map[string]bundle.Output{
"some-output": {
Path: "/tmp/some/path",
Definition: "ParamOne",
},
},
Parameters: map[string]bundle.Parameter{
Expand Down Expand Up @@ -335,9 +333,9 @@ func TestSetOutputsOnClaim(t *testing.T) {

// Non strings given a good type should also work
t.Run("null succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "NullParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "NullParam"
c.Bundle.Outputs["some-output"] = o
output := map[string]string{
"/tmp/some/path": "null",
}
Expand All @@ -346,9 +344,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("boolean succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "BooleanParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "BooleanParam"
c.Bundle.Outputs["some-output"] = o
output := map[string]string{
"/tmp/some/path": "true",
}
Expand All @@ -357,9 +355,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("object succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "ObjectParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "ObjectParam"
c.Bundle.Outputs["some-output"] = o
output := map[string]string{
"/tmp/some/path": "{}",
}
Expand All @@ -368,9 +366,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("array succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field := c.Bundle.Outputs["some-output"]
field.Definition = "ArrayParam"
c.Bundle.Outputs.Fields["some-output"] = field
c.Bundle.Outputs["some-output"] = field
output := map[string]string{
"/tmp/some/path": "[]",
}
Expand All @@ -379,9 +377,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("number succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field := c.Bundle.Outputs["some-output"]
field.Definition = "NumberParam"
c.Bundle.Outputs.Fields["some-output"] = field
c.Bundle.Outputs["some-output"] = field
output := map[string]string{
"/tmp/some/path": "3.14",
}
Expand All @@ -390,9 +388,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("integer as number succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field := c.Bundle.Outputs["some-output"]
field.Definition = "NumberParam"
c.Bundle.Outputs.Fields["some-output"] = field
c.Bundle.Outputs["some-output"] = field
output := map[string]string{
"/tmp/some/path": "372",
}
Expand All @@ -401,9 +399,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
})

t.Run("integer succeeds", func(t *testing.T) {
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "IntegerParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "IntegerParam"
c.Bundle.Outputs["some-output"] = o
output := map[string]string{
"/tmp/some/path": "372",
}
Expand All @@ -415,9 +413,9 @@ func TestSetOutputsOnClaim(t *testing.T) {
func TestSetOutputsOnClaim_MultipleTypes(t *testing.T) {
c := newClaim()
c.Bundle = mockBundle()
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "BooleanAndIntegerParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "BooleanAndIntegerParam"
c.Bundle.Outputs["some-output"] = o

t.Run("BooleanOrInteger, so boolean succeeds", func(t *testing.T) {
output := map[string]string{
Expand All @@ -442,9 +440,9 @@ func TestSetOutputsOnClaim_MultipleTypes(t *testing.T) {
func TestSetOutputsOnClaim_MultipleTypesWithString(t *testing.T) {
c := newClaim()
c.Bundle = mockBundle()
field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "StringAndBooleanParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "StringAndBooleanParam"
c.Bundle.Outputs["some-output"] = o

t.Run("null succeeds", func(t *testing.T) {
output := map[string]string{
Expand All @@ -467,9 +465,9 @@ func TestSetOutputsOnClaim_MismatchType(t *testing.T) {
c := newClaim()
c.Bundle = mockBundle()

field := c.Bundle.Outputs.Fields["some-output"]
field.Definition = "BooleanParam"
c.Bundle.Outputs.Fields["some-output"] = field
o := c.Bundle.Outputs["some-output"]
o.Definition = "BooleanParam"
c.Bundle.Outputs["some-output"] = o

t.Run("error case: content type does not match output definition", func(t *testing.T) {
invalidParsableOutput := map[string]string{
Expand Down
2 changes: 1 addition & 1 deletion bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Bundle struct {
Actions map[string]Action `json:"actions,omitempty" mapstructure:"actions"`
Parameters map[string]Parameter `json:"parameters,omitempty" mapstructure:"parameters"`
Credentials map[string]Credential `json:"credentials,omitempty" mapstructure:"credentials"`
Outputs *OutputsDefinition `json:"outputs,omitempty" mapstructure:"outputs"`
Outputs map[string]Output `json:"outputs,omitempty" mapstructure:"outputs"`
Definitions definition.Definitions `json:"definitions,omitempty" mapstructure:"definitions"`
License string `json:"license,omitempty" mapstructure:"license"`
RequiredExtensions []string `json:"requiredExtensions,omitempty" mapstructure:"requiredExtensions"`
Expand Down
62 changes: 29 additions & 33 deletions bundle/bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,47 +376,45 @@ func TestReadCustomAndRequiredExtensions(t *testing.T) {

func TestOutputs_Marshall(t *testing.T) {
bundleJSON := `
{
"outputs": {
"fields" : {
"clientCert": {
"contentEncoding": "base64",
"contentMediaType": "application/x-x509-user-cert",
"path": "/cnab/app/outputs/clientCert",
"definition": "clientCert"
},
"hostName": {
"applyTo": [
"install"
],
"description": "the hostname produced installing the bundle",
"path": "/cnab/app/outputs/hostname",
"definition": "hostType"
},
"port": {
"path": "/cnab/app/outputs/port",
"definition": "portType"
}
}
{
"outputs":{
"clientCert":{
"contentEncoding":"base64",
"contentMediaType":"application/x-x509-user-cert",
"path":"/cnab/app/outputs/clientCert",
"definition":"clientCert"
},
"hostName":{
"applyTo":[
"install"
],
"description":"the hostname produced installing the bundle",
"path":"/cnab/app/outputs/hostname",
"definition":"hostType"
},
"port":{
"path":"/cnab/app/outputs/port",
"definition":"portType"
}
}
}`
}`

bundle, err := Unmarshal([]byte(bundleJSON))
assert.NoError(t, err, "should have unmarshalled the bundle")
require.NotNil(t, bundle.Outputs, "test must fail, not outputs found")
assert.Equal(t, 3, len(bundle.Outputs.Fields))
assert.Equal(t, 3, len(bundle.Outputs))

clientCert, ok := bundle.Outputs.Fields["clientCert"]
clientCert, ok := bundle.Outputs["clientCert"]
require.True(t, ok, "expected clientCert to exist as an output")
assert.Equal(t, "clientCert", clientCert.Definition)
assert.Equal(t, "/cnab/app/outputs/clientCert", clientCert.Path, "clientCert path was not the expected value")

hostName, ok := bundle.Outputs.Fields["hostName"]
hostName, ok := bundle.Outputs["hostName"]
require.True(t, ok, "expected hostname to exist as an output")
assert.Equal(t, "hostType", hostName.Definition)
assert.Equal(t, "/cnab/app/outputs/hostname", hostName.Path, "hostName path was not the expected value")

port, ok := bundle.Outputs.Fields["port"]
port, ok := bundle.Outputs["port"]
require.True(t, ok, "expected port to exist as an output")
assert.Equal(t, "portType", port.Definition)
assert.Equal(t, "/cnab/app/outputs/port", port.Path, "port path was not the expected value")
Expand Down Expand Up @@ -517,12 +515,10 @@ func TestBundleMarshallAllThings(t *testing.T) {
},
},
},
Outputs: &OutputsDefinition{
Fields: map[string]OutputDefinition{
"clientCert": {
Path: "/cnab/app/outputs/blah",
Definition: "clientCert",
},
Outputs: map[string]Output{
"clientCert": {
Path: "/cnab/app/outputs/blah",
Definition: "clientCert",
},
},
}
Expand Down
6 changes: 1 addition & 5 deletions bundle/outputs.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package bundle

type OutputsDefinition struct {
Fields map[string]OutputDefinition `json:"fields" mapstructure:"fields"`
}

type OutputDefinition struct {
type Output struct {
Definition string `json:"definition" mapstructure:"definition"`
ApplyTo []string `json:"applyTo,omitempty" mapstructure:"applyTo,omitempty"`
Description string `json:"description,omitempty" mapstructure:"description"`
Expand Down
2 changes: 1 addition & 1 deletion testdata/bundles/canonical-bundle.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"credentials":{"password":{"description":"a password","env":"PASSWORD","path":"/cnab/app/path"}},"definitions":{"clientCert":{"contentEncoding":"base64","type":"string"},"enabledType":{"default":false,"type":"boolean"},"hostType":{"default":"locahost.localdomain","type":"string"},"portType":{"default":1234,"type":"integer"},"productKeyType":{"type":"string"},"replicaCountType":{"default":3,"type":"integer"}},"description":"something","images":{"server":{"description":"complicated","image":"nginx:1.0","imageType":"docker"}},"invocationImages":[{"image":"deislabs/invocation-image:1.0","imageType":"docker","labels":{"os":"Linux"}}],"license":"MIT License","name":"testBundle","outputs":{"fields":{"clientCert":{"definition":"clientCert","path":"/cnab/app/outputs/blah"}}},"parameters":{"enabled":{"definition":"enabledType","destination":{"env":"ENABLED"}},"host":{"definition":"hostType","destination":{"env":"HOST"},"required":true},"port":{"definition":"portType","destination":{"env":"PORT"},"required":true},"productKey":{"definition":"productKeyType","destination":{"env":"PRODUCT_KEY"}},"replicaCount":{"definition":"replicaCountType","destination":{"env":"REPLICA_COUNT"}}},"schemaVersion":"v1.0.0-WD","version":"1.0"}
{"credentials":{"password":{"description":"a password","env":"PASSWORD","path":"/cnab/app/path"}},"definitions":{"clientCert":{"contentEncoding":"base64","type":"string"},"enabledType":{"default":false,"type":"boolean"},"hostType":{"default":"locahost.localdomain","type":"string"},"portType":{"default":1234,"type":"integer"},"productKeyType":{"type":"string"},"replicaCountType":{"default":3,"type":"integer"}},"description":"something","images":{"server":{"description":"complicated","image":"nginx:1.0","imageType":"docker"}},"invocationImages":[{"image":"deislabs/invocation-image:1.0","imageType":"docker","labels":{"os":"Linux"}}],"license":"MIT License","name":"testBundle","outputs":{"clientCert":{"definition":"clientCert","path":"/cnab/app/outputs/blah"}},"parameters":{"enabled":{"definition":"enabledType","destination":{"env":"ENABLED"}},"host":{"definition":"hostType","destination":{"env":"HOST"},"required":true},"port":{"definition":"portType","destination":{"env":"PORT"},"required":true},"productKey":{"definition":"productKeyType","destination":{"env":"PRODUCT_KEY"}},"replicaCount":{"definition":"replicaCountType","destination":{"env":"REPLICA_COUNT"}}},"schemaVersion":"v1.0.0-WD","version":"1.0"}