diff --git a/LICENSE b/LICENSE index 261eeb9e..57470c4c 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2019 Dynatrace LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/utils/cmdUtils.go b/pkg/utils/cmdUtils.go new file mode 100644 index 00000000..d6d4ef77 --- /dev/null +++ b/pkg/utils/cmdUtils.go @@ -0,0 +1,20 @@ +package utils + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +// ExecuteCommand exectues the command using the args +func ExecuteCommand(command string, args []string) error { + cmd := exec.Command(command, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + return fmt.Errorf("Error executing command %s %s: %s", command, strings.Join(args, " "), err.Error()) + } + return nil +} diff --git a/pkg/utils/gitHubUtils.go b/pkg/utils/gitHubUtils.go new file mode 100644 index 00000000..b32f37b7 --- /dev/null +++ b/pkg/utils/gitHubUtils.go @@ -0,0 +1,98 @@ +package utils + +import ( + "fmt" + "os" + + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/config" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/transport/http" +) + +// CheckoutConfiguration clons a GitHub repo and checks out the specified branch +func CheckoutConfiguration(gitHubOrg string, project string, branch string) (*git.Repository, error) { + + err := os.RemoveAll(project) + if err != nil { + return nil, err + } + + var repo *git.Repository + if os.Getenv("GITHUB_USERNAME") != "" && os.Getenv("GITHUB_TOKEN") != "" { + // If credentials are available, use them + repo, err = git.PlainClone(project, false, &git.CloneOptions{ + URL: "https://github.com/" + gitHubOrg + "/" + project + ".git", + Auth: &http.BasicAuth{ + Username: os.Getenv("GITHUB_USERNAME"), // anything except an empty string + Password: os.Getenv("GITHUB_TOKEN"), + }, + }) + } else { + repo, err = git.PlainClone(project, false, &git.CloneOptions{ + URL: "https://github.com/" + gitHubOrg + "/" + project + ".git", + }) + } + w, err := repo.Worktree() + if err != nil { + return nil, err + } + + err = repo.Fetch(&git.FetchOptions{ + RefSpecs: []config.RefSpec{"refs/*:refs/*", "HEAD:refs/heads/HEAD"}, + }) + if err != nil { + return nil, err + } + + // Checking out branch + return repo, w.Checkout(&git.CheckoutOptions{ + Branch: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", branch)), + Force: true, + }) +} + +// CheckoutPrevCommit moves the HEAD pointer to the previous commit. It returns the original HEAD. +func CheckoutPrevCommit(repo *git.Repository) (*plumbing.Reference, error) { + + ref, err := repo.Head() + if err != nil { + return nil, err + } + + commitIter, err := repo.Log(&git.LogOptions{From: ref.Hash()}) + if err != nil { + return nil, err + } + + _, err = commitIter.Next() + if err != nil { + return nil, err + } + c, err := commitIter.Next() + if err != nil { + return nil, err + } + + w, err := repo.Worktree() + if err != nil { + return nil, err + } + + return ref, w.Checkout(&git.CheckoutOptions{ + Hash: c.Hash, + }) +} + +// CheckoutReference moves the HEAD pointer to the specified reference. +func CheckoutReference(repo *git.Repository, ref *plumbing.Reference) error { + + w, err := repo.Worktree() + if err != nil { + return err + } + + return w.Checkout(&git.CheckoutOptions{ + Hash: ref.Hash(), + }) +} diff --git a/pkg/utils/kubeUtils.go b/pkg/utils/kubeUtils.go new file mode 100644 index 00000000..0225247f --- /dev/null +++ b/pkg/utils/kubeUtils.go @@ -0,0 +1,24 @@ +package utils + +import ( + "fmt" +) + +func DoHelmUpgrade(project string, stage string) error { + helmChart := fmt.Sprintf("%s/helm-chart", project) + projectStage := fmt.Sprintf("%s-%s", project, stage) + err := ExecuteCommand("helm", []string{"init", "--client-only"}) + if err != nil { + return err + } + err = ExecuteCommand("helm", []string{"dep", "update", helmChart}) + if err != nil { + return err + } + return ExecuteCommand("helm", []string{"upgrade", "--install", projectStage, helmChart, "--namespace", projectStage}) +} + +func CheckDeploymentRolloutStatus(serviceName string, namespace string) error { + + return ExecuteCommand("kubectl", []string{"rollout", "status", "deployment/" + serviceName, "--namespace", namespace}) +} diff --git a/pkg/utils/logger.go b/pkg/utils/logger.go new file mode 100644 index 00000000..77735231 --- /dev/null +++ b/pkg/utils/logger.go @@ -0,0 +1,41 @@ +package utils + +import ( + "encoding/json" + "fmt" +) + +type keptnLogMessage struct { + KeptnContext string `json:"keptnContext"` + Message string `json:"message"` + KeptnService string `json:"keptnService"` + LogLevel string `json:"logLevel"` +} + +const serviceName = "deploy-service" + +// Info logs an info message +func Info(keptnContext string, message string) { + printLogMessage(keptnLogMessage{KeptnContext: keptnContext, Message: message, KeptnService: serviceName, LogLevel: "INFO"}) +} + +// Error logs an error message +func Error(keptnContext string, message string) { + printLogMessage(keptnLogMessage{KeptnContext: keptnContext, Message: message, KeptnService: serviceName, LogLevel: "ERROR"}) +} + +// Debug logs a debug message +func Debug(keptnContext string, message string) { + printLogMessage(keptnLogMessage{KeptnContext: keptnContext, Message: message, KeptnService: serviceName, LogLevel: "DEBUG"}) +} + +func printLogMessage(logMessage keptnLogMessage) { + logString, err := json.Marshal(logMessage) + + if err != nil { + fmt.Println("Could not log keptn log message") + return + } + + fmt.Println(string(logString)) +}