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

Feat: bundle outputs #438

Merged
merged 17 commits into from
Jul 11, 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
2 changes: 2 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ endif

install:
mkdir -p $(HOME)/.porter
cp -R bin/* $(HOME)/.porter/
cp -R bin/bundles $(HOME)/.porter/
cp -R bin/mixins $(HOME)/.porter/
cp bin/porter* $(HOME)/.porter/
ln -f -s $(HOME)/.porter/porter /usr/local/bin/porter

clean: clean-mixins clean-last-testrun
Expand Down
2 changes: 1 addition & 1 deletion build/testdata/bundles/mysql/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Dockerfile
cnab/
.cnab
1 change: 1 addition & 0 deletions build/testdata/bundles/mysql/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ install:
- name: mysql-password
secret: "{{ bundle.parameters.mysql-name }}"
key: mysql-password

uninstall:
- helm:
description: "Uninstall MySQL"
Expand Down
2 changes: 2 additions & 0 deletions build/testdata/bundles/terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Dockerfile
.cnab
11 changes: 11 additions & 0 deletions build/testdata/bundles/terraform/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ install:
autoApprove: true
vars:
file_contents: "{{bundle.parameters.file_contents}}"
outputs:
- name: file_contents

upgrade:
- terraform:
description: "Upgrade Terraform assets"
autoApprove: true
vars:
file_contents: "{{ bundle.parameters.file_contents }}"
outputs:
- name: file_contents

status:
- terraform:
Expand All @@ -34,3 +38,10 @@ uninstall:
description: "Uninstall Terraform assets"
vars:
file_contents: "{{bundle.parameters.file_contents}}"

outputs:
- name: file_contents
type: string
applyTo:
- install
- upgrade
4 changes: 4 additions & 0 deletions build/testdata/bundles/terraform/terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "file_contents" {
value = "${var.file_contents}"
description = "Contents of the file 'foo'"
}
2 changes: 1 addition & 1 deletion build/testdata/bundles/wordpress/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Dockerfile
cnab/
.cnab
13 changes: 13 additions & 0 deletions build/testdata/bundles/wordpress/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,23 @@ install:
externalDatabase.password: "{{ bundle.dependencies.mysql.outputs.mysql-password }}"
externalDatabase.port: 3306
mariadb.enabled: false
outputs:
- name: wordpress-password
secret: "{{ bundle.parameters.wordpress-name }}-wordpress"
key: wordpress-password

uninstall:
- helm:
description: "Uninstall Wordpress"
purge: true
releases:
- "{{ bundle.parameters.wordpress-name }}"

outputs:
- name: wordpress-password
description: "The Wordpress installation password"
type: string
applyTo:
- "install"
- "upgrade"
sensitive: true
40 changes: 39 additions & 1 deletion cmd/porter/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package main
import (
"strings"

"github.com/spf13/cobra"

"github.com/deislabs/porter/pkg/porter"
"github.com/deislabs/porter/pkg/printer"
"github.com/spf13/cobra"
)

func buildBundlesCommand(p *porter.Porter) *cobra.Command {
Expand All @@ -25,6 +26,7 @@ func buildBundlesCommand(p *porter.Porter) *cobra.Command {
cmd.AddCommand(buildBundleInstallCommand(p))
cmd.AddCommand(buildBundleUpgradeCommand(p))
cmd.AddCommand(buildBundleUninstallCommand(p))
cmd.AddCommand(buildBundleShowCommand(p))

return cmd
}
Expand All @@ -37,6 +39,7 @@ func buildBundleAliasCommands(p *porter.Porter) []*cobra.Command {
buildUpgradeCommand(p),
buildUninstallCommand(p),
buildPublishCommand(p),
buildShowCommand(p),
}
}

Expand Down Expand Up @@ -326,3 +329,38 @@ func buildPublishCommand(p *porter.Porter) *cobra.Command {
}
return cmd
}

func buildBundleShowCommand(p *porter.Porter) *cobra.Command {
opts := porter.ShowOptions{}

cmd := cobra.Command{
Use: "show [CLAIM]",
Short: "Show a bundle",
Long: "Displays info relating to a bundle claim, including status and a listing of outputs.",
Example: ` porter bundle show [CLAIM]

Optional output formats include json and yaml.
`,
PreRunE: func(cmd *cobra.Command, args []string) error {
return opts.Validate(args, p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.ShowBundle(opts)
},
}

f := cmd.Flags()
f.StringVarP(&opts.RawFormat, "output", "o", "table",
"Specify an output format. Allowed values: table, json, yaml")

return &cmd
}

func buildShowCommand(p *porter.Porter) *cobra.Command {
cmd := buildBundleShowCommand(p)
cmd.Example = strings.Replace(cmd.Example, "porter bundle show", "porter show", -1)
cmd.Annotations = map[string]string{
"group": "alias",
}
return cmd
}
35 changes: 31 additions & 4 deletions docs/content/authoring-bundles.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Porter generates a bundle from its manifest, porter.yaml. The manifest is made u
* [Bundle Metadata](#bundle-metadata)
* [Mixins](#mixins)
* [Parameters](#parameters)
* [Outputs](#outputs)
* [Credentials](#credentials)
* [Bundle Actions](#bundle-actions)
* [Dependencies](#dependencies)
Expand Down Expand Up @@ -87,11 +88,37 @@ parameters:
* `path`: The path for the file. Required for file paths, there is no default.
* `sensitive`: Optional. Designate this parameter's value as sensitive, for masking in console output.

### Parameter Schema
## Outputs

The [CNAB Spec for parameter definitions](https://github.com/deislabs/cnab-spec/blob/master/101-bundle-json.md#definitions)
has full support for [json schema](https://json-schema.org). We aren't quite there yet but
are working towards it. Here is what Porter supports for defining schema for parameters currently:
Outputs are part of the [CNAB Spec](https://github.com/deislabs/cnab-spec/blob/master/101-bundle-json.md#outputs) to
allow access to outputs generated during the course of executing a bundle. These are global/bundle-wide outputs,
as opposed to step outputs described in [Parameters, Credentials and Outputs](/wiring/). However, as of writing, each
bundle output is only valid if it references a step output declared under one or more [bundle actions](#bundle-actions).

```yaml
outputs:
- name: mysql_user
type: string
description: "MySQL user name"
- name: mysql_password
type: string
applyTo:
- "install"
- "upgrade"
```

* `name`: The name of the output.
* `type`: The data type of the output: string, integer, number, boolean.
* `applyTo`: (Optional) Restrict this output to a given list of actions. If empty or missing, applies to all actions.
* `description`: (Optional) A brief description of the given output.
* `sensitive`: (Optional) Designate an output as sensitive. Defaults to false.

### Definition Schema for Parameters and Outputs

The [CNAB Spec for definitions](https://github.com/deislabs/cnab-spec/blob/master/101-bundle-json.md#definitions)
applies to both parameters and outputs. It has full support for [json schema](https://json-schema.org). We aren't
quite there yet but are working towards it. Here is what Porter supports for defining schema for parameters and outputs
currently:

* `default`: The default value for the parameter. When a default is not provided, the `required` is defaulted to true.
* `required`: Specify if the parameter must be specified when the bundle is executed.
Expand Down
27 changes: 26 additions & 1 deletion docs/content/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Global Flags:
This command is available both as `porter bundle list` and `porter bundles list`.

```console
$ porter bundle list --help
$ porter bundle list --help
List all bundles installed by Porter.

A listing of bundles currently installed by Porter will be provided, along with
Expand All @@ -226,6 +226,31 @@ Global Flags:
--debug Enable debug logging
```

### Bundle Show

This command is available both as `porter bundle show` and `porter bundles show`.

```console
$ porter bundle show --help
Displays info relating to a bundle claim, including status and a listing of outputs.

Usage:
porter bundles show [CLAIM] [flags]

Examples:
porter bundle show [CLAIM]

Optional output formats include json and yaml.


Flags:
-h, --help help for show
-o, --output string Specify an output format. Allowed values: table, json, yaml (default "table")

Global Flags:
--debug Enable debug logging
```

## Mixin Commands

### Mixins List
Expand Down
8 changes: 8 additions & 0 deletions examples/kubernetes-mixin-example/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,21 @@ install:
resourceType: service
resourceName: nginx-deployment
jsonPath: "{.spec.clusterIP}"

- exec:
description: "Echo the IP Address"
command: bash
arguments:
- -c
- "echo 'You will find the service at: {{bundle.outputs.IP_ADDRESS}}'"

uninstall:
- kubernetes:
description: "Uninstall Hello World"
manifests:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch! 😅

- manifests/nginx
wait: true

outputs:
- name: ip_address
type: string
41 changes: 36 additions & 5 deletions pkg/cnab/config_adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package configadapter

import (
"fmt"
"path/filepath"
"strings"

"github.com/deislabs/cnab-go/bundle/definition"
Expand Down Expand Up @@ -35,17 +36,18 @@ func (c *ManifestConverter) ToBundle() *bundle.Bundle {
},
}

b.Definitions = make(definition.Definitions, len(c.Manifest.Parameters)+len(c.Manifest.Outputs))
b.InvocationImages = []bundle.InvocationImage{image}
b.Definitions, b.Parameters = c.generateBundleParameters()
b.Parameters = c.generateBundleParameters(&b.Definitions)
b.Outputs = c.generateBundleOutputs(&b.Definitions)
b.Credentials = c.generateBundleCredentials()
b.Images = c.generateBundleImages()
b.Custom[config.CustomBundleKey] = c.GenerateStamp()

return b
}

func (c *ManifestConverter) generateBundleParameters() (definition.Definitions, *bundle.ParametersDefinition) {
defs := make(definition.Definitions, len(c.Manifest.Parameters))
func (c *ManifestConverter) generateBundleParameters(defs *definition.Definitions) *bundle.ParametersDefinition {
params := &bundle.ParametersDefinition{
Fields: make(map[string]bundle.ParameterDefinition, len(c.Manifest.Parameters)),
}
Expand Down Expand Up @@ -83,10 +85,39 @@ func (c *ManifestConverter) generateBundleParameters() (definition.Definitions,
}
}

defs[param.Name] = d
(*defs)[param.Name] = d
params.Fields[param.Name] = p
}
return defs, params
return params
}

func (c *ManifestConverter) generateBundleOutputs(defs *definition.Definitions) *bundle.OutputsDefinition {
outputs := &bundle.OutputsDefinition{
Fields: make(map[string]bundle.OutputDefinition, len(c.Manifest.Outputs)),
}

for _, output := range c.Manifest.Outputs {
fmt.Fprintf(c.Out, "Generating output definition %s ====>\n", output.Name)
d := &definition.Schema{
Type: output.Type,
Default: output.Default,
Enum: output.Enum,
Minimum: output.Minimum,
Maximum: output.Maximum,
MinLength: output.MinLength,
MaxLength: output.MaxLength,
}
o := bundle.OutputDefinition{
Definition: output.Name,
Description: output.Description,
ApplyTo: output.ApplyTo,
Path: filepath.Join(config.BundleOutputsDir, output.Name),
}

(*defs)[output.Name] = d
outputs.Fields[output.Name] = o
}
return outputs
}

func (c *ManifestConverter) buildDefaultPorterParameters() []config.ParameterDefinition {
Expand Down
Loading