Skip to content

Commit

Permalink
Support secret scope & convert to secret keys to camelCase (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
puthrayaharness authored Mar 6, 2023
1 parent 5a0d06a commit 3d9a08a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ HARNESS_MIGRATOR_AUTH=apiKey harness-upgrade --app APP_ID --project PROJECT --or
```
> If you do not provide use `--triggers` flag it will migrate all triggers in the app
> Migrating Triggers is WIP. The current results requires considerable manual effort post migration
### To create a project
```shell
HARNESS_MIGRATOR_AUTH=apiKey harness-upgrade --account ACCOUNT_ID --env ENV --org ORG project --name PROJECT_NAME --identifier PROJECT_IDENTIFIER create
Expand Down Expand Up @@ -196,6 +198,11 @@ Do a dry run on the files without replacing any CG expressions
harness-upgrade expressions --dry-run
```

Secrets referenced in these files are converted to camel case to align with the migrator. You can provide the scope of the secrets using the `--secret-scope` flag.
```shell
harness-upgrade --secret-scope account expressions
```

To provide custom expressions or override default expressions
```shell
harness-upgrade expressions --override /path/to/file.yaml
Expand Down
35 changes: 31 additions & 4 deletions expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

const ExpressionPattern = "\\$\\{[\\w-.\"()]+}"
const SecretExpressionPattern = "\\$\\{secrets.getValue\\([^{}]+\\)}"

var ExpressionsMap = map[string]string{
"infra.kubernetes.namespace": "<+infra.namespace>",
Expand Down Expand Up @@ -97,14 +98,26 @@ var DynamicExpressions = map[string]interface{}{
"environmentVariables": func(key string) string {
return "<+env.variables." + key + ">"
},
"secrets": func(key string) string {
return "<+secrets.getValue(\"" + key + "\")>"
"secrets.getValue(": func(key string) string {
return "<+secrets.getValue(\"" + getSecretKeyWithScope(key) + "\")>"
},
"app.defaults": func(key string) string {
return "<+variable." + key + ">"
},
}

func getSecretKeyWithScope(key string) string {
camelCase := ToCamelCase(key)
switch migrationReq.SecretScope {
case Account:
return Account + "." + camelCase
case Org:
return Org + "." + camelCase
default:
return camelCase
}
}

func ReplaceCurrentGenExpressionsWithNextGen(*cli.Context) (err error) {
loadYamlFromFile(migrationReq.CustomExpressionsFile)

Expand Down Expand Up @@ -185,8 +198,14 @@ func ReplaceCurrentGenExpressionsWithNextGen(*cli.Context) (err error) {
}

func FindAllExpressions(str string) []string {
// Generic expressions
r := regexp.MustCompile(ExpressionPattern)
return r.FindAllString(str, -1)
allExpressions := r.FindAllString(str, -1)

// Secret expressions
r = regexp.MustCompile(SecretExpressionPattern)
allExpressions = append(allExpressions, r.FindAllString(str, -1)...)
return allExpressions
}

func ReplaceAllExpressions(str string, expressions []string) (string, []string) {
Expand Down Expand Up @@ -248,7 +267,15 @@ func renderSupportedExpressionsTable(data []string) {

func getDynamicExpressionValue(key string) string {
k := getDynamicExpressionKey(key)
dynamic := strings.Replace(key, k+".", "", 1)
var dynamic string
if strings.HasSuffix(k, "(") {
dynamic = strings.Replace(key, k, "", 1)
if strings.HasSuffix(dynamic, ")") {
dynamic = dynamic[0 : len(dynamic)-1]
}
} else {
dynamic = strings.Replace(key, k+".", "", 1)
}
return DynamicExpressions[k].(func(string2 string) string)(dynamic)
}

Expand Down
40 changes: 40 additions & 0 deletions helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,43 @@ func ReadFile(absFilePath string) (string, error) {
}
return string(d), err
}

func ToCamelCase(s string) string {
s = strings.TrimSpace(s)
s = strings.ToLower(s)
if s == "" {
return s
}
n := strings.Builder{}
n.Grow(len(s))
capNext := false
for i, v := range []byte(s) {
vIsCap := v >= 'A' && v <= 'Z'
vIsLow := v >= 'a' && v <= 'z'
vIsNum := v >= '0' && v <= '9'
if vIsNum && i == 0 {
n.WriteByte('_')
}
if capNext {
if vIsLow {
v += 'A'
v -= 'a'
}
} else if i == 0 {
if vIsCap {
v += 'a'
v -= 'A'
}
}
if vIsCap || vIsLow {
n.WriteByte(v)
capNext = false
} else if vIsNum {
n.WriteByte(v)
capNext = true
} else {
capNext = v == '_' || v == ' ' || v == '-' || v == '.'
}
}
return n.String()
}

0 comments on commit 3d9a08a

Please sign in to comment.