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

Commit

Permalink
Add support for secrets in composefiles
Browse files Browse the repository at this point in the history
Signed-off-by: Jean-Christophe Sirot <[email protected]>
  • Loading branch information
Jean-Christophe Sirot committed Oct 4, 2019
1 parent 0942d5c commit c8d3cb0
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
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)
*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)
}

// 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

0 comments on commit c8d3cb0

Please sign in to comment.