Skip to content

Commit

Permalink
fixup; legacy support
Browse files Browse the repository at this point in the history
  • Loading branch information
menehune23 committed Sep 17, 2021
1 parent 3a2f386 commit 76b3032
Show file tree
Hide file tree
Showing 3 changed files with 310 additions and 60 deletions.
130 changes: 113 additions & 17 deletions bindings/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,18 @@ type Resolver struct {
bindings []Binding
}

// NewResolver returns a new service binding resolver. If the SERVICE_BINDING_ROOT environment variable is not set, uses
// the provided platform directory to resolve bindings at `<platformDir>/bindings`.
// NewResolver returns a new service binding resolver. The location of the bindings is given by one of the following, in
// the given order of precedence:
//
// 1. SERVICE_BINDING_ROOT environment variable
// 2. CNB_BINDINGS environment variable, if above is not set
// 3. `<platformDir>/bindings`, if both above are not set
func NewResolver(platformDir string) *Resolver {
root := os.Getenv("SERVICE_BINDING_ROOT")
if root == "" {
root = os.Getenv("CNB_BINDINGS")
}

if root == "" {
root = filepath.Join(platformDir, "bindings")
}
Expand Down Expand Up @@ -123,7 +131,17 @@ func loadBindings(bindingRoot string) ([]Binding, error) {

var bindings []Binding
for _, file := range files {
binding, err := loadBinding(bindingRoot, file.Name())
isLegacy, err := isLegacyBinding(bindingRoot, file.Name())
if err != nil {
return nil, err
}

var binding Binding
if isLegacy {
binding, err = loadLegacyBinding(bindingRoot, file.Name())
} else {
binding, err = loadBinding(bindingRoot, file.Name())
}
if err != nil {
return nil, err
}
Expand All @@ -132,33 +150,111 @@ func loadBindings(bindingRoot string) ([]Binding, error) {
return bindings, nil
}

func loadBinding(bindingRoot, name string) (Binding, error) {
// According to the legacy spec (https://github.com/buildpacks/spec/blob/main/extensions/bindings.md), a legacy binding
// has a `metadata` directory within the binding path.
func isLegacyBinding(bindingRoot string, name string) (bool, error) {
info, err := os.Stat(filepath.Join(bindingRoot, name, "metadata"))
if err == nil {
return info.IsDir(), nil
} else if os.IsNotExist(err) {
return false, nil
}
return false, err
}

func loadBinding(bindingRoot string, name string) (Binding, error) {
binding := Binding{
Name: name,
Path: filepath.Join(bindingRoot, name),
Secret: map[string]SecretReader{},
}

typeBytes, err := ioutil.ReadFile(filepath.Join(binding.Path, "type"))
if err != nil {
return Binding{}, err
}
binding.Type = string(typeBytes)

providerBytes, err := ioutil.ReadFile(filepath.Join(binding.Path, "provider"))
if err != nil && !os.IsNotExist(err) {
return Binding{}, err
}
if err == nil {
binding.Provider = string(providerBytes)
}

secrets, err := loadSecrets(filepath.Join(binding.Path), "type", "provider")
if err != nil {
return Binding{}, err
}
binding.Secret = secrets

return binding, nil
}

// See: https://github.com/buildpacks/spec/blob/main/extensions/bindings.md
func loadLegacyBinding(bindingRoot string, name string) (Binding, error) {
binding := Binding{
Name: name,
Path: filepath.Join(bindingRoot, name),
Secret: map[string]SecretReader{},
}

files, err := ioutil.ReadDir(binding.Path)
typeBytes, err := ioutil.ReadFile(filepath.Join(binding.Path, "metadata", "kind"))
if err != nil {
return Binding{}, err
}
binding.Type = string(typeBytes)

providerBytes, err := ioutil.ReadFile(filepath.Join(binding.Path, "metadata", "provider"))
if err != nil {
return Binding{}, err
}
binding.Provider = string(providerBytes)

metadata, err := loadSecrets(filepath.Join(binding.Path, "metadata"), "kind", "provider")
if err != nil {
return Binding{}, err
}
binding.Secret = metadata

secrets, err := loadSecrets(filepath.Join(binding.Path, "secret"))
if err != nil {
return Binding{}, err
}
for k, v := range secrets {
binding.Secret[k] = v
}

return binding, nil
}

func loadSecrets(secretsPath string, exclude ...string) (map[string]SecretReader, error) {
secrets := map[string]SecretReader{}
files, err := ioutil.ReadDir(secretsPath)
if err != nil {
return Binding{}, nil
return nil, err
}

for _, file := range files {
content, err := os.ReadFile(filepath.Join(binding.Path, file.Name()))
if err != nil {
return Binding{}, err
if in(file.Name(), exclude) {
continue
}

switch file.Name() {
case "type":
binding.Type = string(content)
case "provider":
binding.Provider = string(content)
default:
binding.Secret[file.Name()] = MakeSecretReader(content)
content, err := os.ReadFile(filepath.Join(secretsPath, file.Name()))
if err != nil {
return nil, err
}
secrets[file.Name()] = MakeSecretReader(content)
}
return secrets, nil
}

return binding, nil
func in(item string, list []string) bool {
for _, s := range list {
if s == item {
return true
}
}
return false
}
Loading

0 comments on commit 76b3032

Please sign in to comment.