Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

[WIP] Add support for secrets #671

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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: 4 additions & 0 deletions internal/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ const (
CredentialRegistryName = Namespace + "registry-creds"
// CredentialRegistryPath is the name to the credential containing registry credentials
CredentialRegistryPath = "/cnab/app/registry-creds.json"
// SecretsPath is the directory where secret files are mounted
SecretsPath = "/cnab/app/secrets"
// SecretsParameterPrefix is the prefix used by WriteOnly parameters
SecretsParameterPrefix = Namespace + "secret."

// ParameterOrchestratorName is the name of the parameter containing the orchestrator
ParameterOrchestratorName = Namespace + "orchestrator"
Expand Down
14 changes: 14 additions & 0 deletions internal/packager/cnab.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ func ToCNAB(app *types.App, invocationImageName string) (*bundle.Bundle, error)
Definition: name,
}
}
for name, secret := range app.Secrets() {
writeOnly := new(bool)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the following code is simpler:

writeOnly := true
definitions[internal.SecretsParameterPrefix+name] = &definition.Schema{
	Type:      "string",
	WriteOnly: &writeOnly,
}

*writeOnly = true
definitions[internal.SecretsParameterPrefix+name] = &definition.Schema{
Type: "string",
WriteOnly: writeOnly,
}
parameters[internal.SecretsParameterPrefix+name] = bundle.Parameter{
Destination: &bundle.Location{
Path: secret.NormalizeFilename(),
},
Definition: internal.SecretsParameterPrefix + name,
}
}
var maintainers []bundle.Maintainer
for _, m := range app.Metadata().Maintainers {
maintainers = append(maintainers, bundle.Maintainer{
Expand Down
27 changes: 27 additions & 0 deletions types/secrets/secrets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package secrets

import (
"crypto/sha256"
"fmt"
)

// Secrets represents a secret map
type Secrets map[string]Secret

// Secret represents a secret
type Secret struct {
Path string
External bool
Name string
}

// New creates a new empty secret map
func New() Secrets {
return make(map[string]Secret)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: You can also use the defined type return make(Secrets)

}

// NormalizeFilename generates a filename for this secret to be mounted in the invocation image
func (s *Secret) NormalizeFilename() string {
digest := sha256.Sum256([]byte(s.Path))
return fmt.Sprintf("/cnab/app/secret/%x", digest)
}
36 changes: 36 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import (
"path/filepath"
"strings"

composeloader "github.com/docker/cli/cli/compose/loader"
composetypes "github.com/docker/cli/cli/compose/types"

"github.com/docker/app/internal"
"github.com/docker/app/types/metadata"
"github.com/docker/app/types/parameters"
"github.com/docker/app/types/secrets"
)

// AppSourceKind represents what format the app was in when read
Expand Down Expand Up @@ -41,6 +45,7 @@ type App struct {
composesContent [][]byte
parametersContent [][]byte
parameters parameters.Parameters
secrets secrets.Secrets
metadataContent []byte
metadata metadata.AppMetadata
attachments []Attachment
Expand Down Expand Up @@ -93,6 +98,11 @@ func (a *App) Attachments() []Attachment {
return a.attachments
}

// Secrets returns a map of secrets
func (a *App) Secrets() secrets.Secrets {
return a.secrets
}

func (a *App) HasCRLF() bool {
return a.hasCRLF
}
Expand Down Expand Up @@ -288,10 +298,36 @@ func composeLoader(f func() ([][]byte, error)) func(app *App) error {
return err
}
app.composesContent = append(app.composesContent, composesContent...)
app.secrets = secrets.New()
for _, c := range app.composesContent {
parsedCompose, err := composeloader.ParseYAML(c)
if err != nil {
return err
}
cfg, err := composeloader.Load(composetypes.ConfigDetails{
ConfigFiles: []composetypes.ConfigFile{
{Filename: "docker-compose.yml", Config: parsedCompose},
},
}, withSkipInterpolation)
if err != nil {
return err
}
for name, secret := range cfg.Secrets {
app.secrets[name] = secrets.Secret{
Name: secret.Name,
Path: secret.File,
External: secret.External.External,
}
}
}
return nil
}
}

func withSkipInterpolation(opts *composeloader.Options) {
opts.SkipInterpolation = true
}

func readReaders(readers ...io.Reader) ([][]byte, error) {
content := make([][]byte, len(readers))
var errs []string
Expand Down