Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs committed May 31, 2022
1 parent 1bd482a commit 58dc1e8
Show file tree
Hide file tree
Showing 43 changed files with 1,832 additions and 370 deletions.
2 changes: 1 addition & 1 deletion build/testdata/bundles/wordpress/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
parameters:
database-name: wordpress
mysql-user: wordpress
namespace: wordpress
namespace: wordpress

credentials:
- name: kubeconfig
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ require (
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.1
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869
go.mongodb.org/mongo-driver v1.7.1
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0
go.opentelemetry.io/otel v1.7.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869 h1:7v7L5lsfw4w8iqBBXETukHo4IPltmD+mWoLRYUmeGN8=
github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869/go.mod h1:Rfzr+sqaDreiCaoQbFCu3sTXxeFq/9kXRuyOoSlGQHE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
159 changes: 143 additions & 16 deletions pkg/cnab/config-adapter/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ package configadapter

import (
"context"
"encoding/json"
"fmt"
"path"
"regexp"
"strings"

depsv1 "get.porter.sh/porter/pkg/cnab/dependencies/v1"

"get.porter.sh/porter/pkg/cnab"
depsv2 "get.porter.sh/porter/pkg/cnab/dependencies/v2"
"get.porter.sh/porter/pkg/config"
"get.porter.sh/porter/pkg/manifest"
"get.porter.sh/porter/pkg/mixin"
"get.porter.sh/porter/pkg/tracing"
"github.com/cnabio/cnab-go/bundle"
"github.com/cnabio/cnab-go/bundle/definition"
"github.com/pkg/errors"
)

const SchemaVersion = "v1.0.0"
Expand Down Expand Up @@ -71,7 +77,11 @@ func (c *ManifestConverter) ToBundle(ctx context.Context) (cnab.ExtendedBundle,
b.Outputs = c.generateBundleOutputs(ctx, &b.Definitions)
b.Credentials = c.generateBundleCredentials()
b.Images = c.generateBundleImages()
b.Custom = c.generateCustomExtensions(&b)
extensions, err := c.generateCustomExtensions(&b)
if err != nil {
return b, err
}
b.Custom = extensions
b.RequiredExtensions = c.generateRequiredExtensions(b)

b.Custom[config.CustomPorterKey] = stamp
Expand Down Expand Up @@ -401,24 +411,39 @@ func (c *ManifestConverter) generateBundleImages() map[string]bundle.Image {
return images
}

func (c *ManifestConverter) generateDependencies() *cnab.Dependencies {
func (c *ManifestConverter) generateDependencies() (interface{}, string, error) {
if len(c.Manifest.Dependencies.Requires) == 0 {
return nil, "", nil
}

// Check if they are using v1 of the dependencies spec
if c.Manifest.Dependencies.Requires[0].Reference != "" {
deps := c.generateDependenciesV1()
return deps, cnab.DependenciesV1ExtensionKey, nil
}

// Ok we are using v2!
deps, err := c.generateDependenciesV2()
return deps, cnab.DependenciesV2ExtensionKey, err
}

if len(c.Manifest.Dependencies.RequiredDependencies) == 0 {
func (c *ManifestConverter) generateDependenciesV1() *depsv1.Dependencies {
if len(c.Manifest.Dependencies.Requires) == 0 {
return nil
}

deps := &cnab.Dependencies{
Sequence: make([]string, 0, len(c.Manifest.Dependencies.RequiredDependencies)),
Requires: make(map[string]cnab.Dependency, len(c.Manifest.Dependencies.RequiredDependencies)),
deps := &depsv1.Dependencies{
Sequence: make([]string, 0, len(c.Manifest.Dependencies.Requires)),
Requires: make(map[string]depsv1.Dependency, len(c.Manifest.Dependencies.Requires)),
}

for _, dep := range c.Manifest.Dependencies.RequiredDependencies {
dependencyRef := cnab.Dependency{
for _, dep := range c.Manifest.Dependencies.Requires {
dependencyRef := depsv1.Dependency{
Name: dep.Name,
Bundle: dep.Reference,
}
if len(dep.Versions) > 0 || dep.AllowPrereleases {
dependencyRef.Version = &cnab.DependencyVersion{
dependencyRef.Version = &depsv1.DependencyVersion{
AllowPrereleases: dep.AllowPrereleases,
}
if len(dep.Versions) > 0 {
Expand All @@ -433,6 +458,103 @@ func (c *ManifestConverter) generateDependencies() *cnab.Dependencies {
return deps
}

func (c *ManifestConverter) generateDependenciesV2() (*depsv2.Dependencies, error) {
deps := &depsv2.Dependencies{
Requires: make(map[string]depsv2.Dependency, len(c.Manifest.Dependencies.Requires)),
}

for _, dep := range c.Manifest.Dependencies.Requires {
dependencyRef := depsv2.Dependency{
Name: dep.Name,
Bundle: dep.Bundle.Reference,
}

if len(dep.Bundle.Versions) > 0 || dep.Bundle.AllowPrereleases {
dependencyRef.Version = &depsv2.DependencyVersion{
AllowPrereleases: dep.Bundle.AllowPrereleases,
}
if len(dep.Bundle.Versions) > 0 {
dependencyRef.Version.Ranges = make([]string, len(dep.Bundle.Versions))
copy(dependencyRef.Version.Ranges, dep.Bundle.Versions)
}
}

if dep.Bundle.Interface != nil {
if dep.Bundle.Interface.Reference != "" {
dependencyRef.Interface.Reference = dep.Bundle.Interface.Reference
}
if dep.Bundle.Interface.Document != nil {
bundleData, err := json.Marshal(dep.Bundle.Interface.Document)
if err != nil {
return nil, errors.Wrapf(err, "invalid bundle interface document for dependency %s", dep.Name)
}
rawMessage := &json.RawMessage{}
err = rawMessage.UnmarshalJSON(bundleData)
if err != nil {
return nil, errors.Wrapf(err, "could not convert bundle interface document to a raw json message for dependency %s", dep.Name)
}
dependencyRef.Interface.Document = rawMessage
}
}

if dep.Installation != nil {
dependencyRef.Installation = &depsv2.DependencyInstallation{
Labels: dep.Installation.Labels,
}
if dep.Installation.Criteria != nil {
dependencyRef.Installation.Criteria = &depsv2.InstallationCriteria{
MatchInterface: dep.Installation.Criteria.MatchInterface,
MatchNamespace: dep.Installation.Criteria.MatchNamespace,
IgnoreLabels: dep.Installation.Criteria.IgnoreLabels,
}
}
}

if len(dep.Parameters) > 0 {
dependencyRef.Parameters = make(map[string]depsv2.DependencySource, len(dep.Parameters))
for param, source := range dep.Parameters {
dependencyRef.Parameters[param] = parseDependencySource(source)
}
}

if len(dep.Credentials) > 0 {
dependencyRef.Credentials = make(map[string]depsv2.DependencySource, len(dep.Credentials))
for cred, source := range dep.Credentials {
dependencyRef.Credentials[cred] = parseDependencySource(source)
}
}

deps.Requires[dep.Name] = dependencyRef
}

return deps, nil
}

// TODO: is there a way to feature flag this stuff so that if it's flakey or implemented
// incrementally we can just keep it off?
func parseDependencySource(value string) depsv2.DependencySource {
regex := regexp.MustCompile(`bundle(\.dependencies)?\.([^.]+)\.([^.]+)\.(.+)`)
matches := regex.FindStringSubmatch(value)
if matches == nil || len(matches) < 5 {
return depsv2.DependencySource{Value: value}
}

dependencyName := matches[2] // bundle.dependencies.DEPENDENCY_NAME
itemType := matches[3] // bundle.dependencies.dependency_name.PARAMETERS.name or bundle.OUTPUTS.name
itemName := matches[4] // bundle.dependencies.dependency_name.parameters.NAME or bundle.outputs.NAME

result := depsv2.DependencySource{Dependency: dependencyName}
switch itemType {
case "parameters":
result.Parameter = itemName
case "credentials":
result.Credential = itemName
case "outputs":
result.Output = itemName
}
return result
}

func (c *ManifestConverter) generateParameterSources(b *cnab.ExtendedBundle) cnab.ParameterSources {
ps := cnab.ParameterSources{}

Expand Down Expand Up @@ -581,7 +703,7 @@ func toFloat(v float64) *float64 {
return &v
}

func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) map[string]interface{} {
func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) (map[string]interface{}, error) {
customExtensions := map[string]interface{}{
cnab.FileParameterExtensionKey: struct{}{},
}
Expand All @@ -592,9 +714,12 @@ func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) map
}

// Add the dependency extension
deps := c.generateDependencies()
if deps != nil && len(deps.Requires) > 0 {
customExtensions[cnab.DependenciesExtensionKey] = deps
deps, depsExtKey, err := c.generateDependencies()
if err != nil {
return nil, err
}
if depsExtKey != "" {
customExtensions[depsExtKey] = deps
}

// Add the parameter sources extension
Expand All @@ -608,15 +733,17 @@ func (c *ManifestConverter) generateCustomExtensions(b *cnab.ExtendedBundle) map
customExtensions[lookupExtensionKey(ext.Name)] = ext.Config
}

return customExtensions
return customExtensions, nil
}

func (c *ManifestConverter) generateRequiredExtensions(b cnab.ExtendedBundle) []string {
requiredExtensions := []string{cnab.FileParameterExtensionKey}

// Add the appropriate dependencies key if applicable
if b.HasDependencies() {
requiredExtensions = append(requiredExtensions, cnab.DependenciesExtensionKey)
if b.HasDependenciesV1() {
requiredExtensions = append(requiredExtensions, cnab.DependenciesV1ExtensionKey)
} else if b.HasDependenciesV2() {
requiredExtensions = append(requiredExtensions, cnab.DependenciesV2ExtensionKey)
}

// Add the appropriate parameter sources key if applicable
Expand Down
30 changes: 15 additions & 15 deletions pkg/cnab/config-adapter/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"get.porter.sh/porter/pkg/cnab"
depsv1 "get.porter.sh/porter/pkg/cnab/dependencies/v1"
"get.porter.sh/porter/pkg/config"
"get.porter.sh/porter/pkg/manifest"
"get.porter.sh/porter/pkg/mixin"
Expand Down Expand Up @@ -86,7 +87,7 @@ func TestManifestConverter_ToBundle(t *testing.T) {
assert.Contains(t, bun.Parameters, "porter-debug", "porter-debug parameter was not defined")
assert.Contains(t, bun.Definitions, "porter-debug-parameter", "porter-debug definition was not defined")

assert.True(t, bun.HasDependencies(), "Dependencies was not populated")
assert.True(t, bun.HasDependenciesV1(), "DependenciesV1 was not populated")

assert.Len(t, bun.Outputs, 1, "expected one output for the bundle state")
}
Expand Down Expand Up @@ -539,33 +540,29 @@ func TestManifestConverter_generateDependencies(t *testing.T) {

testcases := []struct {
name string
wantDep cnab.Dependency
wantDep depsv1.Dependency
}{
{"no-version", cnab.Dependency{
{"no-version", depsv1.Dependency{
Name: "mysql",
Bundle: "getporter/azure-mysql:5.7",
}},
{"no-ranges", cnab.Dependency{
{"no-ranges", depsv1.Dependency{
Name: "ad",
Bundle: "getporter/azure-active-directory",
Version: &cnab.DependencyVersion{
Version: &depsv1.DependencyVersion{
AllowPrereleases: true,
},
}},
{"with-ranges", cnab.Dependency{
{"with-ranges", depsv1.Dependency{
Name: "storage",
Bundle: "getporter/azure-blob-storage",
Version: &cnab.DependencyVersion{
Version: &depsv1.DependencyVersion{
Ranges: []string{
"1.x - 2",
"2.1 - 3.x",
},
},
}},
{"with-tag", cnab.Dependency{
Name: "dep-with-tag",
Bundle: "getporter/dep-bun:v0.1.0",
}},
}

for _, tc := range testcases {
Expand All @@ -582,11 +579,14 @@ func TestManifestConverter_generateDependencies(t *testing.T) {

a := NewManifestConverter(c.Config, m, nil, nil)

deps := a.generateDependencies()
require.Len(t, deps.Requires, 4, "incorrect number of dependencies were generated")
require.Equal(t, []string{"mysql", "ad", "storage", "dep-with-tag"}, deps.Sequence, "incorrect sequence was generated")
depsExt, depsExtKey, err := a.generateDependencies()
require.NoError(t, err)
require.Equal(t, cnab.DependenciesV1ExtensionKey, depsExtKey, "expected the v1 dependencies extension key")
require.IsType(t, &depsv1.Dependencies{}, depsExt, "expected a v1 dependencies extension section")
deps := depsExt.(*depsv1.Dependencies)
require.Len(t, deps.Requires, 3, "incorrect number of dependencies were generated")

var dep *cnab.Dependency
var dep *depsv1.Dependency
for _, d := range deps.Requires {
if d.Bundle == tc.wantDep.Bundle {
dep = &d
Expand Down
45 changes: 45 additions & 0 deletions pkg/cnab/config-adapter/testdata/porter-depsv2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
schemaVersion: 1.0.0-alpha.1
name: porter-hello
description: "An example Porter configuration"
version: 0.1.0
registry: "localhost:5000"

credentials:
- name: username
description: Name of the database user
required: false
env: ROOT_USERNAME
- name: password
path: /tmp/password
applyTo:
- uninstall

dependencies:
requires:
- name: mysql
bundle:
reference: "getporter/azure-mysql:5.7"

mixins:
- exec

install:
- exec:
description: "Say Hello"
command: bash
flags:
c: echo Hello World

status:
- exec:
description: "Get World Status"
command: bash
flags:
c: echo The world is on fire

uninstall:
- exec:
description: "Say Goodbye"
command: bash
flags:
c: echo Goodbye World
2 changes: 0 additions & 2 deletions pkg/cnab/config-adapter/testdata/porter-with-deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ dependencies:
versions:
- 1.x - 2
- 2.1 - 3.x
- name: dep-with-tag
reference: "getporter/dep-bun:v0.1.0"

mixins:
- exec
Expand Down
1 change: 1 addition & 0 deletions pkg/cnab/config-adapter/testdata/porter.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies:
requires:
- name: mysql
reference: "getporter/azure-mysql:5.7"

mixins:
- exec

Expand Down
Loading

0 comments on commit 58dc1e8

Please sign in to comment.