Skip to content

Commit

Permalink
✨ Manage encoding when replacing values
Browse files Browse the repository at this point in the history
There is an unused option in kustomize `ReplacementTransformer`
 named `encoding`. We make this option usable an provide 3 encodings:

 - base64
 - hex
 - bcrypt

 This is useful to have values in plain text in replacement sources
 and encode them in the destination.

 The `bcrypt` option may provide some issues has the value would
 change for each run.
  • Loading branch information
antoinemartin committed Feb 10, 2023
1 parent b1f6e4a commit fa6ba12
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 8 deletions.
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func main() {

cmd := command.Build(processor, command.StandaloneDisabled, false)
command.AddGenerateDockerfile(cmd)
cmd.Version = "v0.4.1" // <---VERSION--->
cmd.Version = "v0.4.2" // <---VERSION--->

if err := cmd.Execute(); err != nil {
os.Exit(1)
Expand Down
85 changes: 85 additions & 0 deletions pkg/extras/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package extras

import (
"encoding/base64"
"encoding/hex"
"fmt"
"strings"

"golang.org/x/crypto/bcrypt"
)

// EncodingType enumerates the existing encoding types.
//
//go:generate go run golang.org/x/tools/cmd/stringer -type=EncodingType
type EncodingType int

const (
UnknownEncoding EncodingType = iota
Base64Encoding
BCryptEncoding
HexEncoding
)

var stringToEncodingTypeMap map[string]EncodingType

func init() { //nolint:gochecknoinits
stringToEncodingTypeMap = makeStringToEncodingTypeMap()
}

// makeStringToEncodingTypeMap makes a map to get the appropriate
// [EncodingType] given its name.
func makeStringToEncodingTypeMap() (result map[string]EncodingType) {
result = make(map[string]EncodingType, 3)
for k := range EncoderFactories {
result[strings.Replace(strings.ToLower(k.String()), "encoding", "", 1)] = k
}
return
}

// getEncodingType returns the appropriate [EncodingType] for the passed
// encoding type name
func getEncodingType(n string) EncodingType {
result, ok := stringToEncodingTypeMap[strings.ToLower(n)]
if ok {
return result
}
return UnknownEncoding
}

// Encoder is an encoder function
type Encoder func(value string) (string, error)

// EncodeBase64 encodes value in base64
func EncodeBase64(value string) (string, error) {
return base64.StdEncoding.EncodeToString([]byte(value)), nil
}

// EncodeBcrypt generates the bcrypt hash of value.
func EncodeBcrypt(value string) (string, error) {
encoded, err := bcrypt.GenerateFromPassword([]byte(value), 10)

return string(encoded), err
}

// EncodeHex returns the hex string of value
func EncodeHex(value string) (string, error) {
return hex.EncodeToString([]byte(value)), nil
}

// EncoderFactories register the [Encoder] factory functions for each
// [EncoderType].
var EncoderFactories = map[EncodingType]Encoder{
Base64Encoding: EncodeBase64,
BCryptEncoding: EncodeBcrypt,
HexEncoding: EncodeHex,
}

func GetEncodedValue(value string, encoding string) (string, error) {
et := getEncodingType(encoding)
if f, ok := EncoderFactories[et]; ok {
return f(value)
}

return "", fmt.Errorf("encoding %s is unknown (%d)", encoding, et)
}
26 changes: 26 additions & 0 deletions pkg/extras/encodingtype_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 16 additions & 7 deletions pkg/extras/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,27 @@ func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yam
}

func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
if options == nil || options.Delimiter == "" {
if options == nil || (options.Delimiter == "" && options.Encoding == "") {
return rn, nil
}
if rn.YNode().Kind != yaml.ScalarNode {
return nil, fmt.Errorf("delimiter option can only be used with scalar nodes")
}
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
if options.Index >= len(value) || options.Index < 0 {
return nil, fmt.Errorf("options.index %d is out of bounds for value %s", options.Index, yaml.GetValue(rn))
return nil, fmt.Errorf("delimiter or encoding option can only be used with scalar nodes")
}
n := rn.Copy()
n.YNode().Value = value[options.Index]
if options.Delimiter != "" {
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
if options.Index >= len(value) || options.Index < 0 {
return nil, fmt.Errorf("options.index %d is out of bounds for value %s", options.Index, yaml.GetValue(rn))
}

n.YNode().Value = value[options.Index]
} else {
value, err := GetEncodedValue(yaml.GetValue(rn), options.Encoding)
if err != nil {
return nil, errors.Wrapf(err, "while encoding value")
}
n.YNode().Value = value
}
return n, nil
}

Expand Down
1 change: 1 addition & 0 deletions tests/sourced-replacement/expected/argocd-cm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ data:
teamNameField: slug
orgs:
- name: thisisfakeorganization
b64encoded: VGhpcyBpcyB0aGUgdmFsdWUgdG8gZW5jb2RlIGluIGJhc2U2NA==
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,14 @@ replacements:
name: argocd-cm
fieldPaths:
- data.dex\.config.!!yaml.connectors.[id=github].config.orgs.0.name
- source:
name: autocloud-values
fieldPath: data.to_encode
options:
encoding: base64
targets:
- select:
kind: ConfigMap
name: argocd-cm
fieldPaths:
- data.b64encoded
1 change: 1 addition & 0 deletions tests/sourced-replacement/original/argocd-cm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ data:
teamNameField: slug
orgs:
- name: johndoe
b64encoded: dGhpc2lzZmFrZXZhbHVl
1 change: 1 addition & 0 deletions tests/sourced-replacement/values/properties.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ data:
repo: antoinemartin/autocloud
email: [email protected]
clientID: thisisfakeclientid
to_encode: This is the value to encode in base64

0 comments on commit fa6ba12

Please sign in to comment.