Skip to content

Commit

Permalink
Add support for namespace excluding (#49)
Browse files Browse the repository at this point in the history
* Add support for namespace excluding

* Finish reviewing the code for namespace list resolution
  • Loading branch information
nabsul authored Mar 11, 2023
1 parent 2c49cde commit 907a3cb
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 69 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,5 @@ jobs:
push: true
tags: ${{ steps.meta_ghcr.outputs.tags }}
labels: ${{ steps.meta_ghcr.outputs.labels }}
cache-from: type=gha,scope=k8s-ecr-login-renew
cache-to: type=gha,scope=k8s-ecr-login-renew
cache-from: type=inline
cache-to: type=inline
11 changes: 7 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (
)

const (
envVarAwsSecret = "DOCKER_SECRET_NAME"
envVarTargetNamespace = "TARGET_NAMESPACE"
envVarRegistries = "DOCKER_REGISTRIES"
envVarAwsSecret = "DOCKER_SECRET_NAME"
envVarTargetNamespace = "TARGET_NAMESPACE"
envVarExcludeNamespace = "EXCLUDE_NAMESPACE"
envVarRegistries = "DOCKER_REGISTRIES"
)

func checkErr(err error) {
Expand All @@ -38,7 +39,9 @@ func main() {
servers := getServerList(credentials.Server)
fmt.Printf("Docker Registries: %s\n", strings.Join(servers, ","))

namespaces, err := k8s.GetNamespaces(os.Getenv(envVarTargetNamespace))
targetNamespace := os.Getenv(envVarTargetNamespace)
excludeNamespace := os.Getenv(envVarExcludeNamespace)
namespaces, err := k8s.GetNamespaces(targetNamespace, excludeNamespace)
checkErr(err)
fmt.Printf("Updating kubernetes secret [%s] in %d namespaces\n", name, len(namespaces))

Expand Down
106 changes: 43 additions & 63 deletions src/k8s/namespaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,57 @@ import (
"strings"
)

func GetNamespaces(envVar string) ([]string, error) {
if envVar == "" {
envVar = "default"
func GetNamespaces(includeValue, excludeValue string) ([]string, error) {
var err error
var allNamespaces []string
var includeList, excludeList []*regexp.Regexp

includeList, err = getNamespaceRegexList(includeValue, "default")
if err != nil {
return nil, err
}

envVar = formatNamespaceList(envVar)

list := strings.Split(envVar, ",")
single := make([]string, 0, len(list))
regex := make([]*regexp.Regexp, 0, len(list))

for _, val := range list {
if hasWildCard(val) {
r, err := getRegex(val)
if err != nil {
return nil, err
}
regex = append(regex, r)
} else {
single = append(single, val)
}
excludeList, err = getNamespaceRegexList(excludeValue, "")
if err != nil {
return nil, err
}

matchedNamespaces, err := findNamespaces(regex)
allNamespaces, err = getAllNamespaces()
if err != nil {
return nil, err
}

return unique(append(single, matchedNamespaces...)), nil
result := make([]string, 0)
for _, ns := range allNamespaces {
if isAnyMatch(ns, includeList) && !isAnyMatch(ns, excludeList) {
result = append(result, ns)
}
}

return result, nil
}

func getNamespaceRegexList(value, defaultValue string) ([]*regexp.Regexp, error) {
result := make([]*regexp.Regexp, 0, 0)

if value == "" {
value = defaultValue
}

value = formatNamespaceList(value)
if value == "" {
return result, nil
}

for _, val := range strings.Split(value, ",") {
r, err := getRegex(val)
if err != nil {
return nil, err
}
result = append(result, r)
}

return result, nil
}

var namespaceWhitespace = []string{" ", "\r", "\t", "\v"}
Expand All @@ -55,55 +77,13 @@ func formatNamespaceList(namespaceList string) string {
return formattedNamespaceList
}

func unique(values []string) []string {
result := make([]string, 0, len(values))
check := map[string]bool{}
for _, val := range values {
_, ok := check[val]
if !ok {
check[val] = true
result = append(result, val)
}
}
return result
}

func hasWildCard(val string) bool {
for _, r := range []rune{'*', '?'} {
if strings.ContainsRune(val, r) {
return true
}
}
return false
}

func getRegex(val string) (*regexp.Regexp, error) {
regex := strings.Replace(val, "*", ".*", -1)
regex = strings.Replace(regex, "?", ".", -1)
regex = "^" + regex + "$"
return regexp.Compile(regex)
}

func findNamespaces(regex []*regexp.Regexp) ([]string, error) {
if len(regex) == 0 {
return nil, nil
}

namespaces, err := getAllNamespaces()
if err != nil {
return nil, err
}

result := make([]string, 0, len(namespaces))
for _, ns := range namespaces {
if isAnyMatch(ns, regex) {
result = append(result, ns)
}
}

return result, nil
}

func isAnyMatch(ns string, regexes []*regexp.Regexp) bool {
for _, r := range regexes {
if r.MatchString(ns) {
Expand Down

0 comments on commit 907a3cb

Please sign in to comment.