mirror of
https://github.com/helm/chart-testing.git
synced 2026-02-05 09:45:14 +01:00
* Re-write it in Go
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix loading config from home dir
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Print config
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Remove git gc test code
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Remove year in copyright header
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add alias for lint-and-install
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix examples
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Remove OWNERS file
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add docs generation
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update CircleCI
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update readme
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Document building and releasing
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Remove Makefile
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Hide doc-gen command
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add support for Helm extra args
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update tool dependencies
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update Goreleaser
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Upgrade pip
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update Gopkg.lock
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add log messages
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix CircleCI env var for tag
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add Docker login
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Readme update for MacOS (#1)
* Add build.sh mac prerequisites, and README markdown linting fixes
Signed-off-by: Scott Rigby <scott@r6by.com>
* Update README.md
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update Gopkg.lock
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Update config search locations
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add config files to distro
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add debug flag
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Add note on config files for linting
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix link
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Revert "Update Gopkg.lock"
This reverts commit fcbfbdc9db.
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix link
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
* Fix readme
Signed-off-by: Reinhard Nägele <unguiculus@gmail.com>
139 lines
4.5 KiB
Go
139 lines
4.5 KiB
Go
package tool
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/helm/chart-testing/pkg/exec"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Kubectl struct {
|
|
exec exec.ProcessExecutor
|
|
}
|
|
|
|
func NewKubectl(exec exec.ProcessExecutor) Kubectl {
|
|
return Kubectl{
|
|
exec: exec,
|
|
}
|
|
}
|
|
|
|
// DeleteNamespace deletes the specified namespace. If the namespace does not terminate within 90s, pods running in the
|
|
// namespace and, eventually, the namespace itself are force-deleted.
|
|
func (k Kubectl) DeleteNamespace(namespace string) {
|
|
fmt.Printf("Deleting namespace '%s'...\n", namespace)
|
|
timeoutSec := "120s"
|
|
if err := k.exec.RunProcess("kubectl", "delete", "namespace", namespace, "--timeout", timeoutSec); err != nil {
|
|
fmt.Printf("Namespace '%s' did not terminate after %s.", namespace, timeoutSec)
|
|
}
|
|
|
|
if _, err := k.exec.RunProcessAndCaptureOutput("kubectl", "get", "namespace", namespace); err != nil {
|
|
fmt.Printf("Namespace '%s' terminated.\n", namespace)
|
|
return
|
|
}
|
|
|
|
fmt.Printf("Namespace '%s' did not terminate after %s.", namespace, timeoutSec)
|
|
|
|
fmt.Println("Force-deleting pods...")
|
|
if err := k.exec.RunProcess("kubectl", "delete", "pods", "--namespace", namespace, "--all", "--force", "--grace-period=0"); err != nil {
|
|
fmt.Println("Error deleting pods:", err)
|
|
}
|
|
|
|
time.Sleep(3 * time.Second)
|
|
|
|
if err := k.exec.RunProcess("kubectl", "get", "namespace", namespace); err != nil {
|
|
fmt.Printf("Force-deleting namespace '%s'...\n", namespace)
|
|
if err := k.exec.RunProcess("kubectl", "delete", "namespace", namespace, "--force", "--grace-period=0"); err != nil {
|
|
fmt.Println("Error deleting namespace:", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (k Kubectl) WaitForDeployments(namespace string) error {
|
|
output, err := k.exec.RunProcessAndCaptureOutput(
|
|
"kubectl", "get", "deployments", "--namespace", namespace, "--output", "jsonpath={.items[*].metadata.name}")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
deployments := strings.Fields(output)
|
|
for _, deployment := range deployments {
|
|
deployment = strings.Trim(deployment, "'")
|
|
err := k.exec.RunProcess("kubectl", "rollout", "status", "deployment", deployment, "--namespace", namespace)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 'kubectl rollout status' does not return a non-zero exit code when rollouts fail.
|
|
// We, thus, need to double-check here.
|
|
|
|
pods, err := k.GetPodsforDeployment(namespace, deployment)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, pod := range pods {
|
|
pod = strings.Trim(pod, "'")
|
|
ready, err := k.exec.RunProcessAndCaptureOutput("kubectl", "get", "pod", pod, "--namespace", namespace, "--output",
|
|
`jsonpath={.status.conditions[?(@.type=="Ready")].status}`)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if ready != "True" {
|
|
return errors.New(fmt.Sprintf("Pods '%s' did not reach ready state!", pod))
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (k Kubectl) GetPodsforDeployment(namespace string, deployment string) ([]string, error) {
|
|
jsonString, _ := k.exec.RunProcessAndCaptureOutput("kubectl", "get", "deployment", deployment, "--namespace", namespace, "--output=json")
|
|
var deploymentMap map[string]interface{}
|
|
err := json.Unmarshal([]byte(jsonString), &deploymentMap)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
spec := deploymentMap["spec"].(map[string]interface{})
|
|
selector := spec["selector"].(map[string]interface{})
|
|
matchLabels := selector["matchLabels"].(map[string]interface{})
|
|
var ls string
|
|
for name, value := range matchLabels {
|
|
if ls != "" {
|
|
ls += ","
|
|
}
|
|
ls += fmt.Sprintf("%s=%s", name, value)
|
|
}
|
|
|
|
return k.GetPods("--selector", ls, "--namespace", namespace, "--output", "jsonpath={.items[*].metadata.name}")
|
|
}
|
|
|
|
func (k Kubectl) GetPods(args ...string) ([]string, error) {
|
|
kubectlArgs := []string{"get", "pods"}
|
|
kubectlArgs = append(kubectlArgs, args...)
|
|
pods, err := k.exec.RunProcessAndCaptureOutput("kubectl", kubectlArgs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return strings.Fields(pods), nil
|
|
}
|
|
|
|
func (k Kubectl) DescribePod(namespace string, pod string) error {
|
|
return k.exec.RunProcess("kubectl", "describe", "pod", pod, "--namespace", namespace)
|
|
}
|
|
|
|
func (k Kubectl) Logs(namespace string, pod string, container string) error {
|
|
return k.exec.RunProcess("kubectl", "logs", pod, "--namespace", namespace, "--container", container)
|
|
}
|
|
|
|
func (k Kubectl) GetInitContainers(namespace string, pod string) ([]string, error) {
|
|
return k.GetPods(pod, "--no-headers", "--namespace", namespace, "--output", "jsonpath={.spec.initContainers[*].name}")
|
|
}
|
|
|
|
func (k Kubectl) GetContainers(namespace string, pod string) ([]string, error) {
|
|
return k.GetPods(pod, "--no-headers", "--namespace", namespace, "--output", "jsonpath={.spec.containers[*].name}")
|
|
}
|