Skip to content

Commit

Permalink
Introduce ARM template deployment epam/hub-extensions#36
Browse files Browse the repository at this point in the history
  • Loading branch information
akranga committed Jan 30, 2023
1 parent 4fc5987 commit 60f0919
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 30 deletions.
2 changes: 1 addition & 1 deletion cmd/hub/lifecycle/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func BackupCreate(request *Request, bundles []string, jsonOutput, allowPartial b
componentManifest := manifest.ComponentManifestByRef(componentsManifests, component)
if util.Contains(componentManifest.Lifecycle.Verbs, request.Verb) {
dir := manifest.ComponentSourceDirFromRef(component, stackBaseDir, componentsBaseDir)
impl, _ := probeImplementation(dir, verb)
impl, _ := probeImplementation(dir, verb, componentManifest)
if impl {
implementsBackup = append(implementsBackup, manifest.ComponentQualifiedNameFromRef(component))
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/hub/lifecycle/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ func checkLifecycleVerbs(order []string, components []manifest.ComponentRef, com
if util.Contains(optionalVerbs, verb) {
continue
}
impl, err := probeImplementation(dir, verb)
componentManifest := manifest.ComponentManifestByRef(componentsManifests, component)
impl, err := probeImplementation(dir, verb, componentManifest)
if !impl {
msg := fmt.Sprintf("`%s` component in `%s` has no `%s` implementation: %v",
manifest.ComponentQualifiedNameFromRef(component), dir, verb, err)
manifest := manifest.ComponentManifestByRef(componentsManifests, component)
if manifest.Lifecycle.Bare == "allow" {
if componentManifest.Lifecycle.Bare == "allow" {
if config.Debug {
log.Print(msg)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/hub/lifecycle/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ func delegate(verb string, component *manifest.ComponentRef, componentManifest *
}

processEnv := parametersInEnv(componentName, componentParameters)
impl, err := findImplementation(dir, verb)
impl, err := findImplementation(dir, verb, componentManifest)
if err != nil {
if componentManifest.Lifecycle.Bare == "allow" {
if config.Verbose {
Expand Down
2 changes: 1 addition & 1 deletion cmd/hub/lifecycle/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func Invoke(request *Request) {
if config.Debug {
log.Printf("Component `%s` directory: %s", request.Component, dir)
}
impl, err := findImplementation(dir, request.Verb)
impl, err := findImplementation(dir, request.Verb, componentManifest)
if err != nil {
log.Fatalf("Failed to %s %s: %v", request.Verb, request.Component, err)
}
Expand Down
26 changes: 22 additions & 4 deletions cmd/hub/lifecycle/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/epam/hubctl/cmd/hub/config"
"github.com/epam/hubctl/cmd/hub/ext"
"github.com/epam/hubctl/cmd/hub/manifest"
"github.com/epam/hubctl/cmd/hub/util"
)

Expand All @@ -26,7 +27,7 @@ var hubToSkaffoldVerbs = map[string]string{
"undeploy": "delete",
}

func findImplementation(dir string, verb string) (*exec.Cmd, error) {
func findImplementation(dir string, verb string, component *manifest.Manifest) (*exec.Cmd, error) {
makefile, err := probeMakefile(dir, verb)
if makefile {
binMake, err := exec.LookPath("make")
Expand Down Expand Up @@ -64,11 +65,24 @@ func findImplementation(dir string, verb string) (*exec.Cmd, error) {
if terraform != "" {
return &exec.Cmd{Path: terraform, Args: append([]string{terraform}, args...), Dir: dir}, nil
}
arm, args, err7 := probeArm(dir, verb, component)
if arm != "" {
return &exec.Cmd{Path: arm, Args: append([]string{arm}, args...), Dir: dir}, nil
}

return nil, fmt.Errorf("No `%s` implementation found in `%s`: %s",
verb, dir, util.Errors("; ", err, err2, err3, err4, err5, err6))
verb, dir, util.Errors("; ", err, err2, err3, err4, err5, err6, err7))
}

func probeArm(dir string, verb string, component *manifest.Manifest) (string, []string, error) {
if util.Contains(component.Requires, "arm") {
path, args, err := ext.ExtensionPath([]string{"component", "arm", verb}, nil)
return path, args, err
}
return "", []string{verb}, nil
}

func probeImplementation(dir string, verb string) (bool, error) {
func probeImplementation(dir string, verb string, component *manifest.Manifest) (bool, error) {
makefile, err := probeMakefile(dir, verb)
if makefile {
return true, nil
Expand All @@ -93,7 +107,11 @@ func probeImplementation(dir string, verb string) (bool, error) {
if terraform != "" {
return true, nil
}
allErrs := util.Errors("; ", err, err2, err3, err4, err5, err6)
arm, _, err7 := probeArm(dir, verb, component)
if arm != "" {
return true, nil
}
allErrs := util.Errors("; ", err, err2, err3, err4, err5, err6, err7)
if config.Debug {
log.Printf("Found no `%s` implementations in `%s`: %s",
verb, dir, allErrs)
Expand Down
15 changes: 10 additions & 5 deletions cmd/hub/lifecycle/requirement.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func setupRequirement(requirement string, provider string,
case "kubectl", "kubernetes":
kube.SetupKubernetes(parameters, provider, outputs, "", false, false)

case "aws", "azure", "gcp", "gcs",
case "aws", "azure", "arm", "gcp", "gcs",
"tiller", "external-dns", "cert-manager",
"helm", "terraform", "etcd", "vault", "ingress", "tls-ingress", "istio":
wellKnown, err := checkRequire(requirement)
Expand All @@ -161,6 +161,7 @@ func setupRequirement(requirement string, provider string,

var bins = map[string][]string{
"aws": {"aws", "s3", "ls", "--page-size", "5"},
"azure": {"az", "version"},
"gcp": {"gcloud", "version"},
"gcs": {"gsutil", "version"},
"kubectl": {"kubectl", "version", "--client"},
Expand Down Expand Up @@ -218,11 +219,16 @@ func checkRequire(require string) (bool, error) {
return true, nil
}
switch require {
case "azure":
case "azure", "arm":
err := checkRequiresAzure()
if err != nil {
return true, err
}
bin := bins["azure"]
_, err = checkRequiresBin(bin...)
if err != nil {
util.WarnOnce("Error accessing `%s` binary: %v", bin[0], err)
}
setupTerraformAzureOsEnv()

case "aws", "gcp", "gcs", "kubectl", "kubernetes", "helm", "terraform", "vault": // "etcd"
Expand Down Expand Up @@ -339,15 +345,14 @@ func setupTerraformAzureOsEnv() {
}
}
}
for _, v := range []string{"ARM_CLIENT_ID", "ARM_CLIENT_SECRET", "ARM_SUBSCRIPTION_ID", "ARM_TENANT_ID"} {

for _, v := range []string{"ARM_SUBSCRIPTION_ID", "ARM_CLIENT_ID", "ARM_CLIENT_SECRET", "ARM_SUBSCRIPTION_ID", "ARM_TENANT_ID"} {
src := "AZURE" + v[3:]
if value := os.Getenv(src); value != "" {
if config.Trace {
log.Printf("Setting %s=%s", v, value)
}
os.Setenv(v, value)
} else {
util.Warn("Unable to set %s: no %s env var set", v, src)
}
}
// TODO ARM_USE_MSI ARM_ENVIRONMENT?
Expand Down
37 changes: 22 additions & 15 deletions cmd/hub/lifecycle/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,11 +569,14 @@ func bcryptStr(str string) (string, error) {
}

// Splits the string into a list of strings
// First argument is a string to split
// Second optional argument is a separator (default is space)
//
// First argument is a string to split
// Second optional argument is a separator (default is space)
//
// Example:
// split "a b c" => ["a", "b", "c"]
// split "a-b-c", "-" => ["a", "b", "c"]
//
// split "a b c" => ["a", "b", "c"]
// split "a-b-c", "-" => ["a", "b", "c"]
func split(args ...string) ([]string, error) {
if len(args) == 0 {
return nil, fmt.Errorf("split expects one or two arguments")
Expand All @@ -588,9 +591,10 @@ func split(args ...string) ([]string, error) {
// Accepts variable arguments arguments (easier tolerate template nature):
//
// Example:
// compact "string1" (compatibility with parametersx)
// compact "string1" "string2" "string3"
// compact ["string1", "string2", "string3"]
//
// compact "string1" (compatibility with parametersx)
// compact "string1" "string2" "string3"
// compact ["string1", "string2", "string3"]
func compact(args ...interface{}) ([]string, error) {
var results []string
for _, arg := range args {
Expand Down Expand Up @@ -625,10 +629,11 @@ func compact(args ...interface{}) ([]string, error) {
// Accepts variable arguments arguments (easier tolerate template nature)
//
// Example:
// join "string1" "string2" "delimiter"
// join ["string1", "string2"] "delimiter"
// join ["string1", "string2"]
// join "string1"
//
// join "string1" "string2" "delimiter"
// join ["string1", "string2"] "delimiter"
// join ["string1", "string2"]
// join "string1"
func join(args ...interface{}) (string, error) {
if len(args) == 0 {
return "", fmt.Errorf("join expects at least one argument")
Expand Down Expand Up @@ -667,7 +672,8 @@ func join(args ...interface{}) (string, error) {
// Returns the first argument from list
//
// Example:
// first ["string1" "string2" "string3"] => "string1"
//
// first ["string1" "string2" "string3"] => "string1"
func first(args []string) (string, error) {
if len(args) == 0 {
return "", fmt.Errorf("first expects at least one argument")
Expand All @@ -680,9 +686,10 @@ func first(args []string) (string, error) {
// '.' is not allowed
//
// Arguments:
// First argument is a text to convert
// Second optional argument is a size of the name (default is 63)
// Third optional argument is a delimiter (default is '-')
//
// First argument is a text to convert
// Second optional argument is a size of the name (default is 63)
// Third optional argument is a delimiter (default is '-')
func formatSubdomain(args ...interface{}) (string, error) {
if len(args) == 0 {
return "", fmt.Errorf("hostname expects at least one argument")
Expand Down
9 changes: 9 additions & 0 deletions cmd/hub/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ func Warn(format string, v ...interface{}) {
}
}

func Coalesce(values ...string) string {
for _, v := range values {
if v != "" {
return v
}
}
return ""
}

func WarnOnce(format string, v ...interface{}) {
msg := fmt.Sprintf(format, v...)
if _, emitted := warningsEmitted[msg]; emitted {
Expand Down
5 changes: 5 additions & 0 deletions cmd/hub/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1222,3 +1222,8 @@ func TestMaybeEnv(t *testing.T) {
})
}
}

func TestCoalesce(t *testing.T) {
assert.Equal(t, "a", Coalesce("", "a", "b", "c"))
assert.Equal(t, "", Coalesce("", "", "", ""))
}

0 comments on commit 60f0919

Please sign in to comment.