diff --git a/Gopkg.lock b/Gopkg.lock index 47b37ec8..a8607f44 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -180,6 +180,14 @@ revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" version = "v1.1.1" +[[projects]] + branch = "master" + digest = "1:f5537515bc64edb9117ec396d197d88852d927185352ce08e2667562ef532a96" + name = "github.com/deislabs/cnab-go" + packages = ["bundle"] + pruneopts = "NUT" + revision = "1a73873b84025123a0f8fe84086e59493e051302" + [[projects]] digest = "1:e71d64468873ca819b91b975e67e71f349a89f41ab38040bcbd8840f5e193654" name = "github.com/docker/cli" @@ -753,14 +761,6 @@ pruneopts = "NUT" revision = "418d78d0b9a7b7de3a6bbc8a23def624cc977bb2" -[[projects]] - digest = "1:3fd3d634f6815f19ac4b2c5e16d28ec9aa4584d0bba25d1ee6c424d813cca22a" - name = "github.com/renstrom/fuzzysearch" - packages = ["fuzzy"] - pruneopts = "NUT" - revision = "b18e754edff4833912ef4dce9eaca885bd3f0de1" - version = "v1.0.1" - [[projects]] digest = "1:01252cd79aac70f16cac02a72a1067dd136e0ad6d5b597d0129cf74c739fd8d1" name = "github.com/sirupsen/logrus" @@ -869,17 +869,9 @@ [[projects]] branch = "master" - digest = "1:5a72a3eacbfef7b5ecf165c9e5b1f38f24c4a023a8c1490c138daf37eec9101b" + digest = "1:cb77e5934866333fa0784326a57e64c4da128001c94fbd1d29819d79bd3b1087" name = "golang.org/x/crypto" packages = [ - "cast5", - "openpgp", - "openpgp/armor", - "openpgp/clearsign", - "openpgp/elgamal", - "openpgp/errors", - "openpgp/packet", - "openpgp/s2k", "pbkdf2", "ssh/terminal", ] @@ -1186,6 +1178,7 @@ analyzer-version = 1 input-imports = [ "github.com/Masterminds/semver", + "github.com/deislabs/cnab-go/bundle", "github.com/docker/cli/cli/command", "github.com/docker/cli/cli/command/image/build", "github.com/docker/cli/cli/config", @@ -1196,7 +1189,6 @@ "github.com/docker/distribution/reference", "github.com/docker/docker/api/types", "github.com/docker/docker/api/types/container", - "github.com/docker/docker/api/types/mount", "github.com/docker/docker/api/types/strslice", "github.com/docker/docker/builder/dockerignore", "github.com/docker/docker/client", @@ -1212,17 +1204,13 @@ "github.com/gosuri/uitable", "github.com/oklog/ulid", "github.com/opencontainers/go-digest", - "github.com/renstrom/fuzzysearch/fuzzy", + "github.com/pkg/errors", "github.com/sirupsen/logrus", "github.com/spf13/cobra", "github.com/spf13/pflag", "github.com/spf13/viper", "github.com/stretchr/testify/assert", "github.com/technosophos/moniker", - "golang.org/x/crypto/openpgp", - "golang.org/x/crypto/openpgp/armor", - "golang.org/x/crypto/openpgp/clearsign", - "golang.org/x/crypto/openpgp/packet", "golang.org/x/net/context", "gopkg.in/AlecAivazis/survey.v1", "gopkg.in/yaml.v2", diff --git a/Gopkg.toml b/Gopkg.toml index bba6298f..93480b9a 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -10,10 +10,6 @@ name = "github.com/Masterminds/semver" version = "1.4.2" -[[constraint]] - name = "github.com/Masterminds/vcs" - version = "1.11.1" - [[constraint]] name = "github.com/sirupsen/logrus" version = "v1.0.4" diff --git a/cmd/duffle/build.go b/cmd/duffle/build.go index c4a2280f..b7373973 100644 --- a/cmd/duffle/build.go +++ b/cmd/duffle/build.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" + "github.com/deislabs/cnab-go/bundle" "github.com/docker/cli/cli/command" cliconfig "github.com/docker/cli/cli/config" dockerdebug "github.com/docker/cli/cli/debug" @@ -19,7 +20,6 @@ import ( "github.com/spf13/pflag" "github.com/deislabs/duffle/pkg/builder" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/crypto/digest" "github.com/deislabs/duffle/pkg/duffle/home" "github.com/deislabs/duffle/pkg/duffle/manifest" diff --git a/cmd/duffle/claims_show_test.go b/cmd/duffle/claims_show_test.go index d4cd1238..96817339 100644 --- a/cmd/duffle/claims_show_test.go +++ b/cmd/duffle/claims_show_test.go @@ -5,9 +5,9 @@ import ( "encoding/json" "testing" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/cmd/duffle/claims_test.go b/cmd/duffle/claims_test.go index 9b0d672c..d067d4a1 100644 --- a/cmd/duffle/claims_test.go +++ b/cmd/duffle/claims_test.go @@ -4,9 +4,9 @@ import ( "errors" "testing" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/cmd/duffle/credential_generate.go b/cmd/duffle/credential_generate.go index 0f0d6381..46918c61 100644 --- a/cmd/duffle/credential_generate.go +++ b/cmd/duffle/credential_generate.go @@ -9,11 +9,11 @@ import ( "sort" "strings" + "github.com/deislabs/cnab-go/bundle" "github.com/spf13/cobra" survey "gopkg.in/AlecAivazis/survey.v1" yaml "gopkg.in/yaml.v2" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/credentials" "github.com/deislabs/duffle/pkg/duffle/home" ) diff --git a/cmd/duffle/credential_generate_test.go b/cmd/duffle/credential_generate_test.go index 29738bbe..4b94059b 100644 --- a/cmd/duffle/credential_generate_test.go +++ b/cmd/duffle/credential_generate_test.go @@ -3,7 +3,7 @@ package main import ( "testing" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/cmd/duffle/install.go b/cmd/duffle/install.go index 035e823d..a38c262c 100644 --- a/cmd/duffle/install.go +++ b/cmd/duffle/install.go @@ -7,11 +7,11 @@ import ( "path/filepath" "strings" + "github.com/deislabs/cnab-go/bundle" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/deislabs/duffle/pkg/action" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" "github.com/deislabs/duffle/pkg/duffle/home" "github.com/deislabs/duffle/pkg/repo" diff --git a/cmd/duffle/install_test.go b/cmd/duffle/install_test.go index 3fa832f6..8f0f3ee0 100644 --- a/cmd/duffle/install_test.go +++ b/cmd/duffle/install_test.go @@ -6,9 +6,9 @@ import ( "path/filepath" "testing" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/duffle/home" ) diff --git a/cmd/duffle/main.go b/cmd/duffle/main.go index 0b604303..7847765d 100644 --- a/cmd/duffle/main.go +++ b/cmd/duffle/main.go @@ -7,9 +7,9 @@ import ( "runtime" "strings" + "github.com/deislabs/cnab-go/bundle" "github.com/spf13/cobra" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" "github.com/deislabs/duffle/pkg/credentials" "github.com/deislabs/duffle/pkg/driver" diff --git a/cmd/duffle/main_test.go b/cmd/duffle/main_test.go index 83a516c0..9595bc0d 100644 --- a/cmd/duffle/main_test.go +++ b/cmd/duffle/main_test.go @@ -6,13 +6,12 @@ import ( "path/filepath" "testing" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/credentials" + "github.com/deislabs/duffle/pkg/duffle/home" + "github.com/deislabs/cnab-go/bundle" "github.com/ghodss/yaml" "github.com/stretchr/testify/assert" - - "github.com/deislabs/duffle/pkg/duffle/home" ) func CreateTestHome(t *testing.T) home.Home { diff --git a/cmd/duffle/root_test.go b/cmd/duffle/root_test.go index 820ff711..04a673fe 100644 --- a/cmd/duffle/root_test.go +++ b/cmd/duffle/root_test.go @@ -10,7 +10,8 @@ import ( "strings" "testing" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" + "github.com/deislabs/duffle/pkg/version" ) diff --git a/cmd/duffle/upgrade_test.go b/cmd/duffle/upgrade_test.go index 155b1d83..4951931f 100644 --- a/cmd/duffle/upgrade_test.go +++ b/cmd/duffle/upgrade_test.go @@ -6,7 +6,8 @@ import ( "path/filepath" "testing" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" + "github.com/deislabs/duffle/pkg/claim" ) diff --git a/pkg/action/action.go b/pkg/action/action.go index adea8e04..e6f7c276 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -7,7 +7,8 @@ import ( "io" "strings" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" + "github.com/deislabs/duffle/pkg/claim" "github.com/deislabs/duffle/pkg/credentials" "github.com/deislabs/duffle/pkg/driver" diff --git a/pkg/action/action_test.go b/pkg/action/action_test.go index 4bbb1079..48a1a6bb 100644 --- a/pkg/action/action_test.go +++ b/pkg/action/action_test.go @@ -8,11 +8,11 @@ import ( "testing" "time" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" "github.com/deislabs/duffle/pkg/credentials" "github.com/deislabs/duffle/pkg/driver" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/pkg/action/run_custom_test.go b/pkg/action/run_custom_test.go index 068c5205..34648ce3 100644 --- a/pkg/action/run_custom_test.go +++ b/pkg/action/run_custom_test.go @@ -5,10 +5,10 @@ import ( "testing" "time" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/claim" "github.com/deislabs/duffle/pkg/driver" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index ff4710cc..0acdbe78 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -11,9 +11,9 @@ import ( "time" "github.com/Masterminds/semver" + "github.com/deislabs/cnab-go/bundle" "github.com/pkg/errors" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/duffle/manifest" "github.com/deislabs/duffle/pkg/imagebuilder" ) diff --git a/pkg/builder/builder_test.go b/pkg/builder/builder_test.go index 421b5a4d..a7d7d983 100644 --- a/pkg/builder/builder_test.go +++ b/pkg/builder/builder_test.go @@ -6,7 +6,8 @@ import ( "reflect" "testing" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" + "github.com/deislabs/duffle/pkg/duffle/manifest" "github.com/deislabs/duffle/pkg/imagebuilder" ) diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go deleted file mode 100644 index edcd5778..00000000 --- a/pkg/bundle/bundle.go +++ /dev/null @@ -1,178 +0,0 @@ -package bundle - -import ( - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - - "github.com/docker/go/canonical/json" -) - -// Bundle is a CNAB metadata document -type Bundle struct { - Name string `json:"name" mapstructure:"name"` - Version string `json:"version" mapstructure:"version"` - Description string `json:"description" mapstructure:"description"` - Keywords []string `json:"keywords,omitempty" mapstructure:"keywords"` - Maintainers []Maintainer `json:"maintainers,omitempty" mapstructure:"maintainers"` - InvocationImages []InvocationImage `json:"invocationImages" mapstructure:"invocationImages"` - Images map[string]Image `json:"images" mapstructure:"images"` - Actions map[string]Action `json:"actions,omitempty" mapstructure:"actions"` - Parameters map[string]ParameterDefinition `json:"parameters" mapstructure:"parameters"` - Credentials map[string]Location `json:"credentials" mapstructure:"credentials"` -} - -func Unmarshal(data []byte) (*Bundle, error) { - b := &Bundle{} - return b, json.Unmarshal(data, b) -} - -// ParseReader reads CNAB metadata from a JSON string -func ParseReader(r io.Reader) (Bundle, error) { - b := Bundle{} - err := json.NewDecoder(r).Decode(&b) - return b, err -} - -// WriteFile serializes the bundle and writes it to a file as JSON. -func (b Bundle) WriteFile(dest string, mode os.FileMode) error { - d, err := json.MarshalCanonical(b) - if err != nil { - return err - } - return ioutil.WriteFile(dest, d, mode) -} - -// WriteTo writes JSON to an io.Writer using the standard formatting. -func (b Bundle) WriteTo(w io.Writer) (int64, error) { - d, err := json.MarshalCanonical(b) - if err != nil { - return 0, err - } - l, err := w.Write(d) - return int64(l), err -} - -// LocationRef specifies a location within the invocation package -type LocationRef struct { - Path string `json:"path" mapstructure:"path"` - Field string `json:"field" mapstructure:"field"` - MediaType string `json:"mediaType" mapstructure:"mediaType"` -} - -// BaseImage contains fields shared across image types -type BaseImage struct { - ImageType string `json:"imageType" mapstructure:"imageType"` - Image string `json:"image" mapstructure:"image"` - Digest string `json:"digest,omitempty" mapstructure:"digest"` - Size uint64 `json:"size,omitempty" mapstructure:"size"` - Platform *ImagePlatform `json:"platform,omitempty" mapstructure:"platform"` - MediaType string `json:"mediaType,omitempty" mapstructure:"mediaType"` -} - -// ImagePlatform indicates what type of platform an image is built for -type ImagePlatform struct { - Architecture string `json:"architecture,omitempty" mapstructure:"architecture"` - OS string `json:"os,omitempty" mapstructure:"os"` -} - -// Image describes a container image in the bundle -type Image struct { - BaseImage `mapstructure:",squash"` - Description string `json:"description" mapstructure:"description"` //TODO: change? see where it's being used? change to description? -} - -// InvocationImage contains the image type and location for the installation of a bundle -type InvocationImage struct { - BaseImage `mapstructure:",squash"` -} - -// Location provides the location where a value should be written in -// the invocation image. -// -// A location may be either a file (by path) or an environment variable. -type Location struct { - Path string `json:"path,omitempty" mapstructure:"path"` - EnvironmentVariable string `json:"env,omitempty" mapstructure:"env"` -} - -// Maintainer describes a code maintainer of a bundle -type Maintainer struct { - // Name is a user name or organization name - Name string `json:"name" mapstructure:"name"` - // Email is an optional email address to contact the named maintainer - Email string `json:"email,omitempty" mapstructure:"email"` - // Url is an optional URL to an address for the named maintainer - URL string `json:"url,omitempty" mapstructure:"url"` -} - -// Action describes a custom (non-core) action. -type Action struct { - // Modifies indicates whether this action modifies the release. - // - // If it is possible that an action modify a release, this must be set to true. - Modifies bool `json:"modifies,omitempty" mapstructure:"modifies"` - // Stateless indicates that the action is purely informational, that credentials are not required, and that the runtime should not keep track of its invocation - Stateless bool `json:"stateless,omitempty" mapstructure:"stateless"` - // Description describes the action as a user-readable string - Description string `json:"description,omitempty" mapstructure:"description"` -} - -// ValuesOrDefaults returns parameter values or the default parameter values -func ValuesOrDefaults(vals map[string]interface{}, b *Bundle) (map[string]interface{}, error) { - res := map[string]interface{}{} - for name, def := range b.Parameters { - if val, ok := vals[name]; ok { - if err := def.ValidateParameterValue(val); err != nil { - return res, fmt.Errorf("can't use %v as value of %s: %s", val, name, err) - } - typedVal := def.CoerceValue(val) - res[name] = typedVal - continue - } else if def.Required { - return res, fmt.Errorf("parameter %q is required", name) - } - res[name] = def.DefaultValue - } - return res, nil -} - -// Validate the bundle contents. -func (b Bundle) Validate() error { - if len(b.InvocationImages) == 0 { - return errors.New("at least one invocation image must be defined in the bundle") - } - - if b.Version == "latest" { - return errors.New("'latest' is not a valid bundle version") - } - - for _, img := range b.InvocationImages { - err := img.Validate() - if err != nil { - return err - } - } - - return nil -} - -// Validate the image contents. -func (img InvocationImage) Validate() error { - switch img.ImageType { - case "docker", "oci": - return validateDockerish(img.Image) - default: - return nil - } -} - -func validateDockerish(s string) error { - if !strings.Contains(s, ":") { - return errors.New("tag is required") - } - return nil -} diff --git a/pkg/bundle/bundle_test.go b/pkg/bundle/bundle_test.go deleted file mode 100644 index 16666760..00000000 --- a/pkg/bundle/bundle_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package bundle - -import ( - "io/ioutil" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestReadTopLevelProperties(t *testing.T) { - json := `{ - "name": "foo", - "version": "1.0", - "images": {}, - "credentials": {} - }` - bundle, err := Unmarshal([]byte(json)) - if err != nil { - t.Fatal(err) - } - if bundle.Name != "foo" { - t.Errorf("Expected name 'foo', got '%s'", bundle.Name) - } - if bundle.Version != "1.0" { - t.Errorf("Expected version '1.0', got '%s'", bundle.Version) - } - if len(bundle.Images) != 0 { - t.Errorf("Expected no images, got %d", len(bundle.Images)) - } - if len(bundle.Credentials) != 0 { - t.Errorf("Expected no credentials, got %d", len(bundle.Credentials)) - } -} - -func TestReadImageProperties(t *testing.T) { - data, err := ioutil.ReadFile("../../tests/testdata/bundles/foo.json") - if err != nil { - t.Errorf("cannot read bundle file: %v", err) - } - - bundle, err := Unmarshal(data) - if err != nil { - t.Fatal(err) - } - if len(bundle.Images) != 2 { - t.Errorf("Expected 2 images, got %d", len(bundle.Images)) - } - image1 := bundle.Images["image1"] - if image1.Description != "image1" { - t.Errorf("Expected description 'image1', got '%s'", image1.Description) - } - if image1.Image != "urn:image1uri" { - t.Errorf("Expected Image 'urn:image1uri', got '%s'", image1.Image) - } -} - -func TestReadCredentialProperties(t *testing.T) { - data, err := ioutil.ReadFile("../../tests/testdata/bundles/foo.json") - if err != nil { - t.Errorf("cannot read bundle file: %v", err) - } - - bundle, err := Unmarshal(data) - if err != nil { - t.Fatal(err) - } - if len(bundle.Credentials) != 3 { - t.Errorf("Expected 3 credentials, got %d", len(bundle.Credentials)) - } - f := bundle.Credentials["foo"] - if f.Path != "pfoo" { - t.Errorf("Expected path 'pfoo', got '%s'", f.Path) - } - if f.EnvironmentVariable != "" { - t.Errorf("Expected env '', got '%s'", f.EnvironmentVariable) - } - b := bundle.Credentials["bar"] - if b.Path != "" { - t.Errorf("Expected path '', got '%s'", b.Path) - } - if b.EnvironmentVariable != "ebar" { - t.Errorf("Expected env 'ebar', got '%s'", b.EnvironmentVariable) - } - q := bundle.Credentials["quux"] - if q.Path != "pquux" { - t.Errorf("Expected path 'pquux', got '%s'", q.Path) - } - if q.EnvironmentVariable != "equux" { - t.Errorf("Expected env 'equux', got '%s'", q.EnvironmentVariable) - } -} - -func TestValuesOrDefaults(t *testing.T) { - is := assert.New(t) - vals := map[string]interface{}{ - "port": 8080, - "host": "localhost", - "enabled": true, - } - b := &Bundle{ - Parameters: map[string]ParameterDefinition{ - "port": { - DataType: "int", - DefaultValue: 1234, - }, - "host": { - DataType: "string", - DefaultValue: "localhost.localdomain", - }, - "enabled": { - DataType: "bool", - DefaultValue: false, - }, - "replicaCount": { - DataType: "int", - DefaultValue: 3, - }, - }, - } - - vod, err := ValuesOrDefaults(vals, b) - - is.NoError(err) - is.True(vod["enabled"].(bool)) - is.Equal(vod["host"].(string), "localhost") - is.Equal(vod["port"].(int), 8080) - is.Equal(vod["replicaCount"].(int), 3) - - // This should err out because of type problem - vals["replicaCount"] = "banana" - _, err = ValuesOrDefaults(vals, b) - is.Error(err) -} - -func TestValuesOrDefaults_Required(t *testing.T) { - is := assert.New(t) - vals := map[string]interface{}{ - "enabled": true, - } - b := &Bundle{ - Parameters: map[string]ParameterDefinition{ - "minimum": { - DataType: "int", - Required: true, - }, - "enabled": { - DataType: "bool", - DefaultValue: false, - }, - }, - } - - _, err := ValuesOrDefaults(vals, b) - is.Error(err) - - // It is unclear what the outcome should be when the user supplies - // empty values on purpose. For now, we will assume those meet the - // minimum definition of "required", and that other rules will - // correct for empty values. - // - // Example: It makes perfect sense for a user to specify --set minimum=0 - // and in so doing meet the requirement that a value be specified. - vals["minimum"] = 0 - res, err := ValuesOrDefaults(vals, b) - is.NoError(err) - is.Equal(0, res["minimum"]) -} - -func TestValidateVersionTag(t *testing.T) { - is := assert.New(t) - - img := InvocationImage{BaseImage{}} - b := Bundle{ - Version: "latest", - InvocationImages: []InvocationImage{img}, - } - - err := b.Validate() - is.EqualError(err, "'latest' is not a valid bundle version") -} - -func TestValidateBundle_RequiresInvocationImage(t *testing.T) { - b := Bundle{ - Name: "bar", - Version: "0.1.0", - } - - err := b.Validate() - if err == nil { - t.Fatal("Validate should have failed because the bundle has no invocation images") - } - - b.InvocationImages = append(b.InvocationImages, InvocationImage{}) - - err = b.Validate() - if err != nil { - t.Fatal(err) - } -} diff --git a/pkg/bundle/parameters.go b/pkg/bundle/parameters.go deleted file mode 100644 index 4b85dcf5..00000000 --- a/pkg/bundle/parameters.go +++ /dev/null @@ -1,181 +0,0 @@ -package bundle - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -// ParameterDefinition defines a single parameter for a CNAB bundle -type ParameterDefinition struct { - DataType string `json:"type" mapstructure:"type"` - DefaultValue interface{} `json:"defaultValue,omitempty" mapstructure:"defaultValue"` - AllowedValues []interface{} `json:"allowedValues,omitempty" mapstructure:"allowedValues"` - Required bool `json:"required,omitempty" mapstructure:"required"` - MinValue *int `json:"minValue,omitempty" mapstructure:"minValue"` - MaxValue *int `json:"maxValue,omitempty" mapstructure:"maxValue"` - MinLength *int `json:"minLength,omitempty" mapstructure:"minLength"` - MaxLength *int `json:"maxLength,omitempty" mapstructure:"maxLength"` - Metadata *ParameterMetadata `json:"metadata,omitempty" mapstructure:"metadata"` - Destination *Location `json:"destination,omitemtpty" mapstructure:"destination"` - ApplyTo []string `json:"apply-to,omitempty" mapstructure:"apply-to,omitempty"` -} - -// ParameterMetadata contains metadata for a parameter definition. -type ParameterMetadata struct { - Description string `json:"description,omitempty" mapstructure:"description"` -} - -// ValidateParameterValue checks whether a value is valid as the value of -// the specified parameter. -func (pd ParameterDefinition) ValidateParameterValue(value interface{}) error { - if err := pd.validateByType(value); err != nil { - return err - } - - return pd.validateAllowedValue(value) -} -func (pd ParameterDefinition) validateByType(value interface{}) error { - switch pd.DataType { - case "string": - return pd.validateStringParameterValue(value) - case "int": - return pd.validateIntParameterValue(value) - case "bool": - return pd.validateBoolParameterValue(value) - default: - return errors.New("invalid parameter definition") - } -} - -func (pd ParameterDefinition) validateAllowedValue(value interface{}) error { - if len(pd.AllowedValues) > 0 { - val := pd.CoerceValue(value) - if !isInCollection(val, pd.allowedValues()) { - return errors.New("value is not in the set of allowed values for this parameter") - } - } - return nil -} - -func (pd ParameterDefinition) allowedValues() []interface{} { - if pd.DataType == "int" { - return intify(pd.AllowedValues) - } - return pd.AllowedValues -} - -// "Allowed value" numeric collections loaded from JSON will be materialised -// by Go as float64. We support only ints and so want to treat them as such. -func intify(values []interface{}) []interface{} { - result := []interface{}{} - for _, v := range values { - f, ok := v.(float64) - if ok { - result = append(result, int(f)) - } else { - result = append(result, v) - } - } - return result -} - -// CoerceValue coerces the given value to the definition's DataType; -// unlike ConvertValue, which performs string parsing, it assumes the -// value is already of a suitable type (and validated) -func (pd ParameterDefinition) CoerceValue(value interface{}) interface{} { - if pd.DataType == "int" { - f, ok := value.(float64) - if ok { - i, ok := asInt(f) - if !ok { - return f - } - return i - } - } - return value -} - -// ConvertValue tries to convert the given value to the definition's DataType -// -// It will return an error if it cannot be converted -func (pd ParameterDefinition) ConvertValue(val string) (interface{}, error) { - switch pd.DataType { - case "string": - return val, nil - case "int": - return strconv.Atoi(val) - case "bool": - if strings.ToLower(val) == "true" { - return true, nil - } else if strings.ToLower(val) == "false" { - return false, nil - } else { - return false, fmt.Errorf("%q is not a valid boolean", val) - } - default: - return nil, errors.New("invalid parameter definition") - } -} - -func (pd ParameterDefinition) validateStringParameterValue(value interface{}) error { - s, ok := value.(string) - if !ok { - return errors.New("value is not a string") - } - if pd.MinLength != nil && len(s) < *pd.MinLength { - return fmt.Errorf("value is too short: minimum length is %d", *pd.MinLength) - } - if pd.MaxLength != nil && len(s) > *pd.MaxLength { - return fmt.Errorf("value is too long: maximum length is %d", *pd.MaxLength) - } - return nil -} - -func (pd ParameterDefinition) validateIntParameterValue(value interface{}) error { - i, ok := value.(int) - if !ok { - f, ok := value.(float64) - if !ok { - return errors.New("value is not a number") - } - i, ok = asInt(f) - if !ok { - return errors.New("value is not an integer") - } - } - if pd.MinValue != nil && i < *pd.MinValue { - return fmt.Errorf("value is too low: minimum value is %d", *pd.MinValue) - } - if pd.MaxValue != nil && i > *pd.MaxValue { - return fmt.Errorf("value is too high: maximum value is %d", *pd.MaxValue) - } - return nil -} - -func (pd ParameterDefinition) validateBoolParameterValue(value interface{}) error { - _, ok := value.(bool) - if !ok { - return errors.New("value is not a boolean") - } - return nil -} - -func isInCollection(value interface{}, values []interface{}) bool { - for _, v := range values { - if value == v { - return true - } - } - return false -} - -func asInt(f float64) (int, bool) { - i := int(f) - if float64(i) != f { - return 0, false - } - return i, true -} diff --git a/pkg/bundle/parameters_test.go b/pkg/bundle/parameters_test.go deleted file mode 100644 index aa734c51..00000000 --- a/pkg/bundle/parameters_test.go +++ /dev/null @@ -1,377 +0,0 @@ -package bundle - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCanReadParameterNames(t *testing.T) { - json := `{ - "parameters": { - "foo": { }, - "bar": { } - } - }` - definitions, err := Unmarshal([]byte(json)) - if err != nil { - t.Fatal(err) - } - if len(definitions.Parameters) != 2 { - t.Fatalf("Expected 2 parameter definitons, got %d", len(definitions.Parameters)) - } - if _, ok := definitions.Parameters["foo"]; !ok { - t.Errorf("Expected an entry with name 'foo' but didn't get one") - } - if _, ok := definitions.Parameters["bar"]; !ok { - t.Errorf("Expected an entry with name 'bar' but didn't get one") - } -} - -func TestCanReadParameterDefinition(t *testing.T) { - dataType := "int" - defaultValue := "some default" - allowedValues0 := "foo" - allowedValues1 := "bar" - minValue := 100 - maxValue := 200 - minLength := 300 - maxLength := 400 - description := "some description" - action0 := "action0" - action1 := "action1" - - json := fmt.Sprintf(`{ - "parameters": { - "test": { - "type": "%s", - "defaultValue": "%s", - "allowedValues": [ "%s", "%s" ], - "minValue": %d, - "maxValue": %d, - "minLength": %d, - "maxLength": %d, - "metadata": { - "description": "%s" - }, - "apply-to": [ "%s", "%s" ] - } - } - }`, - dataType, defaultValue, allowedValues0, allowedValues1, - minValue, maxValue, minLength, maxLength, description, - action0, action1) - - definitions, err := Unmarshal([]byte(json)) - if err != nil { - t.Fatal(err) - } - - p := definitions.Parameters["test"] - if p.DataType != dataType { - t.Errorf("Expected data type '%s' but got '%s'", dataType, p.DataType) - } - if p.DefaultValue != defaultValue { - t.Errorf("Expected default value '%s' but got '%s'", defaultValue, p.DefaultValue) - } - if len(p.AllowedValues) != 2 { - t.Errorf("Expected 2 allowed values but got %d", len(p.AllowedValues)) - } - if p.AllowedValues[0] != allowedValues0 { - t.Errorf("Expected allowed value '%s' but got '%s'", allowedValues0, p.AllowedValues[0]) - } - if p.AllowedValues[1] != allowedValues1 { - t.Errorf("Expected allowed value '%s' but got '%s'", allowedValues1, p.AllowedValues[1]) - } - if *p.MinValue != minValue { - t.Errorf("Expected min value '%d' but got '%d'", minValue, p.MinValue) - } - if *p.MinLength != minLength { - t.Errorf("Expected min length '%d' but got '%d'", minLength, p.MinLength) - } - if *p.MaxValue != maxValue { - t.Errorf("Expected max value '%d' but got '%d'", maxValue, p.MaxValue) - } - if *p.MaxLength != maxLength { - t.Errorf("Expected max length '%d' but got '%d'", maxLength, p.MaxLength) - } - if p.Metadata.Description != description { - t.Errorf("Expected description '%s' but got '%s'", description, p.Metadata.Description) - } - if len(p.ApplyTo) != 2 { - t.Errorf("Expected 2 apply-to actions but got %d", len(p.ApplyTo)) - } - if p.ApplyTo[0] != action0 { - t.Errorf("Expected action '%s' but got '%s'", action0, p.ApplyTo[0]) - } - if p.ApplyTo[1] != action1 { - t.Errorf("Expected action '%s' but got '%s'", action1, p.ApplyTo[1]) - } -} - -func valueTestJSON(jsonRepresentation string) []byte { - return []byte(fmt.Sprintf(`{ - "parameters": { - "test": { - "defaultValue": %s, - "allowedValues": [ %s ] - } - } - }`, jsonRepresentation, jsonRepresentation)) -} - -func expectString(desc string, expected string, o interface{}, t *testing.T) { - s, ok := o.(string) - if !ok { - t.Errorf("Expected string %s but didn't get one", desc) - } - if s != expected { - t.Errorf("Expected %s '%s' but got '%s'", desc, expected, s) - } -} - -func expectInt(desc string, expected int, o interface{}, t *testing.T) { - i, ok := o.(float64) - if !ok { - t.Errorf("Expected int %s but didn't get one", desc) - } - if int(i) != expected { - t.Errorf("Expected %s '%d' but got '%d'", desc, expected, int(i)) - } -} - -func expectBool(desc string, expected bool, o interface{}, t *testing.T) { - b, ok := o.(bool) - if !ok { - t.Errorf("Expected bool %s but didn't get one", desc) - } - if b != expected { - t.Errorf("Expected %s '%t' but got '%t'", desc, expected, b) - } -} - -func TestCanReadValues(t *testing.T) { - strValue := "\"some string\"" - intValue := "123" - boolValue := "true" - - strDef, err := Unmarshal(valueTestJSON(strValue)) - if err != nil { - t.Fatal(err) - } - expectString("default value", "some string", strDef.Parameters["test"].DefaultValue, t) - expectString("allowed value", "some string", strDef.Parameters["test"].AllowedValues[0], t) - - intDef, err := Unmarshal(valueTestJSON(intValue)) - if err != nil { - t.Fatal(err) - } - expectInt("default value", 123, intDef.Parameters["test"].DefaultValue, t) - expectInt("allowed value", 123, intDef.Parameters["test"].AllowedValues[0], t) - - boolDef, err := Unmarshal(valueTestJSON(boolValue)) - if err != nil { - t.Fatal(err) - } - expectBool("default value", true, boolDef.Parameters["test"].DefaultValue, t) - expectBool("allowed value", true, boolDef.Parameters["test"].AllowedValues[0], t) -} - -func TestValidateStringParameterValue_AnyAllowed(t *testing.T) { - pd := ParameterDefinition{ - DataType: "string", - } - - err := pd.ValidateParameterValue("foo") - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(17) - if err == nil { - t.Errorf("Expected invalid type but got no error") - } -} - -func TestValidateStringParameterValue_AllowedOnly(t *testing.T) { - pd := ParameterDefinition{ - DataType: "string", - AllowedValues: []interface{}{"foo", "bar"}, - } - - err := pd.ValidateParameterValue("foo") - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue("quux") - if err == nil { - t.Errorf("Expected disallowed value but got no error") - } -} - -func TestValidateStringParameterValue_MinLength(t *testing.T) { - pd := ParameterDefinition{ - DataType: "string", - MinLength: intPtr(5), - } - - err := pd.ValidateParameterValue("foobar") - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue("foo") - if err == nil { - t.Errorf("Expected too-short value but got no error") - } -} - -func TestValidateStringParameterValue_MaxLength(t *testing.T) { - pd := ParameterDefinition{ - DataType: "string", - MaxLength: intPtr(5), - } - - err := pd.ValidateParameterValue("foo") - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue("foobar") - if err == nil { - t.Errorf("Expected too-long value but got no error") - } -} - -func TestValidateIntParameterValue_AnyAllowed(t *testing.T) { - pd := ParameterDefinition{ - DataType: "int", - } - - err := pd.ValidateParameterValue(17) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(float64(17)) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(17.5) - if err == nil { - t.Errorf("Expected not an integer but got no error") - } - - err = pd.ValidateParameterValue("17") - if err == nil { - t.Errorf("Expected invalid type but got no error") - } -} - -func TestValidateIntParameterValue_AllowedOnly(t *testing.T) { - pd := ParameterDefinition{ - DataType: "int", - AllowedValues: []interface{}{17, 23}, - } - - err := pd.ValidateParameterValue(17) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(58) - if err == nil { - t.Errorf("Expected disallowed value but got no error") - } -} - -func TestValidateIntParameterValue_MinValue(t *testing.T) { - pd := ParameterDefinition{ - DataType: "int", - MinValue: intPtr(5), - } - - err := pd.ValidateParameterValue(17) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(3) - if err == nil { - t.Errorf("Expected too-small value but got no error") - } - assert.Equal(t, "value is too low: minimum value is 5", err.Error()) -} - -func TestValidateIntParameterValue_MaxValue(t *testing.T) { - pd := ParameterDefinition{ - DataType: "int", - MaxValue: intPtr(5), - } - - err := pd.ValidateParameterValue(3) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(17) - if err == nil { - t.Errorf("Expected too-large value but got no error") - } - assert.Equal(t, "value is too high: maximum value is 5", err.Error()) -} - -func TestValidateBoolParameterValue(t *testing.T) { - pd := ParameterDefinition{ - DataType: "bool", - } - - err := pd.ValidateParameterValue(true) - if err != nil { - t.Errorf("Expected valid but got error %s", err) - } - - err = pd.ValidateParameterValue(17) - if err == nil { - t.Errorf("Expected invalid type but got no error") - } - - err = pd.ValidateParameterValue("17") - if err == nil { - t.Errorf("Expected invalid type but got no error") - } -} - -func TestConvertValue(t *testing.T) { - pd := ParameterDefinition{ - DataType: "bool", - } - is := assert.New(t) - - out, _ := pd.ConvertValue("true") - is.True(out.(bool)) - out, _ = pd.ConvertValue("false") - is.False(out.(bool)) - out, _ = pd.ConvertValue("barbeque") - is.False(out.(bool)) - - pd.DataType = "string" - out, err := pd.ConvertValue("hello") - is.NoError(err) - is.Equal("hello", out.(string)) - - pd.DataType = "int" - out, err = pd.ConvertValue("123") - is.NoError(err) - is.Equal(123, out.(int)) - - _, err = pd.ConvertValue("onetwothree") - is.Error(err) -} - -func intPtr(i int) *int { - return &i -} diff --git a/pkg/bundle/replacement/jsonreplacer.go b/pkg/bundle/replacement/jsonreplacer.go deleted file mode 100644 index eb8c6826..00000000 --- a/pkg/bundle/replacement/jsonreplacer.go +++ /dev/null @@ -1,55 +0,0 @@ -package replacement - -import ( - "encoding/json" -) - -// NewJSONReplacer creates a Replacer for JSON documents. -func NewJSONReplacer(indent string) Replacer { - return jsonReplacer{ - indent: indent, - } -} - -type jsonReplacer struct { - indent string -} - -func (r jsonReplacer) Replace(source string, selector string, value string) (string, error) { - dict := make(map[string]interface{}) - err := json.Unmarshal([]byte(source), &dict) - - if err != nil { - return "", err - } - - selectorPath := parseSelector(selector) - err = replaceIn(jsonDocMap(dict), selectorPath, value) - if err != nil { - return "", err - } - - bytes, err := json.MarshalIndent(dict, "", r.indent) - if err != nil { - return "", err - } - return string(bytes), nil -} - -type jsonDocMap map[string]interface{} - -func (m jsonDocMap) get(key string) (interface{}, bool) { - e, ok := m[key] - return e, ok -} - -func (m jsonDocMap) set(key string, value interface{}) { - m[key] = value -} - -func (m jsonDocMap) asInstance(value interface{}) (docmap, bool) { - if e, ok := value.(map[string]interface{}); ok { - return jsonDocMap(e), ok - } - return jsonDocMap{}, false -} diff --git a/pkg/bundle/replacement/jsonreplacer_test.go b/pkg/bundle/replacement/jsonreplacer_test.go deleted file mode 100644 index 35ce72f2..00000000 --- a/pkg/bundle/replacement/jsonreplacer_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package replacement - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCanReplaceInJSON(t *testing.T) { - source := `{ - "a": 1, - "b": { - "c": "d", - "e": "f" - } -}` - r := NewJSONReplacer("\t") - result, err := r.Replace(source, "b.c", "test") - if err != nil { - t.Fatalf("Replace failed: %s", err) - } - - expected := strings.Replace(source, "d", "test", -1) - - is := assert.New(t) - is.Equal(strings.TrimSpace(expected), strings.TrimSpace(result)) -} - -func TestJSONErrorIfPathNotFound(t *testing.T) { - source := `{ - "a": 1, - "b": { - "c": "d", - "e": "f" - } -}` - r := NewJSONReplacer("\t") - - _, err := r.Replace(source, "b.c.d", "test") - if err != ErrSelectorNotFound { - t.Error("Expected path not found error for b.c.d") - } - - _, err = r.Replace(source, "b.d", "test") - if err != ErrSelectorNotFound { - t.Error("Expected path not found error for b.d") - } -} diff --git a/pkg/bundle/replacement/replacer.go b/pkg/bundle/replacement/replacer.go deleted file mode 100644 index b8b4947a..00000000 --- a/pkg/bundle/replacement/replacer.go +++ /dev/null @@ -1,14 +0,0 @@ -package replacement - -import "errors" - -// Replacer replaces the values of fields matched by a selector. -type Replacer interface { - Replace(source string, selector string, value string) (string, error) -} - -var ( - // ErrSelectorNotFound is reported when the document does not - // contain a field matching the selector. - ErrSelectorNotFound = errors.New("Selector not found") -) diff --git a/pkg/bundle/replacement/utils.go b/pkg/bundle/replacement/utils.go deleted file mode 100644 index a132fb4c..00000000 --- a/pkg/bundle/replacement/utils.go +++ /dev/null @@ -1,36 +0,0 @@ -package replacement - -import ( - "strings" -) - -// Abstraction over map to permit generic traversal and substitution -type docmap interface { - get(key string) (interface{}, bool) - set(key string, value interface{}) - asInstance(value interface{}) (docmap, bool) -} - -func parseSelector(selector string) []string { - return strings.Split(selector, ".") -} - -func replaceIn(dict docmap, selectorPath []string, value string) error { - entry, ok := dict.get(selectorPath[0]) - if !ok { - return ErrSelectorNotFound - } - - if len(selectorPath) == 1 { - dict.set(selectorPath[0], value) - return nil - } - - entryDict, ok := dict.asInstance(entry) - if !ok { - return ErrSelectorNotFound // Because we have reached a terminal with some of the selectorPath to go - } - rest := selectorPath[1:] - - return replaceIn(entryDict, rest, value) -} diff --git a/pkg/bundle/replacement/yamlreplacer.go b/pkg/bundle/replacement/yamlreplacer.go deleted file mode 100644 index 203d5078..00000000 --- a/pkg/bundle/replacement/yamlreplacer.go +++ /dev/null @@ -1,52 +0,0 @@ -package replacement - -import ( - yaml "gopkg.in/yaml.v2" -) - -// NewYAMLReplacer creates a Replacer for YAML documents. -func NewYAMLReplacer() Replacer { - return yamlReplacer{} -} - -type yamlReplacer struct { -} - -func (r yamlReplacer) Replace(source string, selector string, value string) (string, error) { - dict := make(map[interface{}]interface{}) - err := yaml.Unmarshal([]byte(source), dict) - - if err != nil { - return "", err - } - - selectorPath := parseSelector(selector) - err = replaceIn(yamlDocMap(dict), selectorPath, value) - if err != nil { - return "", err - } - - bytes, err := yaml.Marshal(dict) - if err != nil { - return "", err - } - return string(bytes), nil -} - -type yamlDocMap map[interface{}]interface{} - -func (m yamlDocMap) get(key string) (interface{}, bool) { - e, ok := m[key] - return e, ok -} - -func (m yamlDocMap) set(key string, value interface{}) { - m[key] = value -} - -func (m yamlDocMap) asInstance(value interface{}) (docmap, bool) { - if e, ok := value.(map[interface{}]interface{}); ok { - return yamlDocMap(e), ok - } - return yamlDocMap{}, false -} diff --git a/pkg/bundle/replacement/yamlreplacer_test.go b/pkg/bundle/replacement/yamlreplacer_test.go deleted file mode 100644 index 347e7636..00000000 --- a/pkg/bundle/replacement/yamlreplacer_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package replacement - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCanReplaceInYAML(t *testing.T) { - source := "a: 1\nb:\n c: d\n e: f" - r := NewYAMLReplacer() - result, err := r.Replace(source, "b.c", "test") - if err != nil { - t.Fatalf("Replace failed: %s", err) - } - - expected := strings.Replace(source, "d", "test", -1) - - is := assert.New(t) - is.Equal(strings.TrimSpace(expected), strings.TrimSpace(result)) -} - -func TestYAMLErrorIfPathNotFound(t *testing.T) { - source := "a: 1\nb:\n c: d\n e: f" - r := NewYAMLReplacer() - - _, err := r.Replace(source, "b.c.d", "test") - if err != ErrSelectorNotFound { - t.Error("Expected path not found error for b.c.d") - } - - _, err = r.Replace(source, "b.d", "test") - if err != ErrSelectorNotFound { - t.Error("Expected path not found error for b.d") - } -} diff --git a/pkg/claim/claim.go b/pkg/claim/claim.go index 57380ec4..7cf90505 100644 --- a/pkg/claim/claim.go +++ b/pkg/claim/claim.go @@ -8,7 +8,7 @@ import ( "github.com/oklog/ulid" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" ) // Status constants define the CNAB status fields on a Result. diff --git a/pkg/claim/claimstore_test.go b/pkg/claim/claimstore_test.go index e0078407..af352c96 100644 --- a/pkg/claim/claimstore_test.go +++ b/pkg/claim/claimstore_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/utils/crud" ) diff --git a/pkg/credentials/credentialset.go b/pkg/credentials/credentialset.go index a0f24332..aa42467a 100644 --- a/pkg/credentials/credentialset.go +++ b/pkg/credentials/credentialset.go @@ -7,7 +7,7 @@ import ( "os/exec" "strings" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" yaml "gopkg.in/yaml.v2" ) diff --git a/pkg/credentials/credentialset_test.go b/pkg/credentials/credentialset_test.go index 0eb7b082..cb3a5fd9 100644 --- a/pkg/credentials/credentialset_test.go +++ b/pkg/credentials/credentialset_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" "github.com/stretchr/testify/assert" ) diff --git a/pkg/duffle/manifest/create.go b/pkg/duffle/manifest/create.go index a88d5e09..14d5e7f0 100644 --- a/pkg/duffle/manifest/create.go +++ b/pkg/duffle/manifest/create.go @@ -7,7 +7,7 @@ import ( "github.com/docker/go/canonical/json" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" ) const runContent = `#!/bin/bash diff --git a/pkg/duffle/manifest/manifest.go b/pkg/duffle/manifest/manifest.go index 11b50108..7c98f1d3 100644 --- a/pkg/duffle/manifest/manifest.go +++ b/pkg/duffle/manifest/manifest.go @@ -4,7 +4,7 @@ import ( "os" "path/filepath" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" "github.com/technosophos/moniker" ) diff --git a/pkg/loader/loader.go b/pkg/loader/loader.go index 37c85287..3d07ec24 100644 --- a/pkg/loader/loader.go +++ b/pkg/loader/loader.go @@ -7,7 +7,7 @@ import ( "net/url" "os" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" ) // Loader provides an interface for loading a bundle diff --git a/pkg/packager/export.go b/pkg/packager/export.go index c5916840..290f9684 100644 --- a/pkg/packager/export.go +++ b/pkg/packager/export.go @@ -9,11 +9,11 @@ import ( "strings" "time" + "github.com/deislabs/cnab-go/bundle" "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/docker/docker/pkg/archive" - "github.com/deislabs/duffle/pkg/bundle" "github.com/deislabs/duffle/pkg/loader" ) diff --git a/pkg/repo/remote/index.go b/pkg/repo/remote/index.go index 6c0b465e..b9d703d4 100644 --- a/pkg/repo/remote/index.go +++ b/pkg/repo/remote/index.go @@ -12,7 +12,7 @@ import ( "github.com/Masterminds/semver" - "github.com/deislabs/duffle/pkg/bundle" + "github.com/deislabs/cnab-go/bundle" ) const (