Implement components selection
- add components global flag - install selected components - check selected components
This commit is contained in:
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -14,11 +15,16 @@ import (
|
|||||||
|
|
||||||
var checkCmd = &cobra.Command{
|
var checkCmd = &cobra.Command{
|
||||||
Use: "check",
|
Use: "check",
|
||||||
Short: "Check requirements",
|
Short: "Check requirements and installation",
|
||||||
Long: `
|
Long: `
|
||||||
The check command will perform a series of checks to validate that
|
The check command will perform a series of checks to validate that
|
||||||
the local environment is configured correctly.`,
|
the local environment is configured correctly and if the installed components are healthy.`,
|
||||||
Example: ` check --pre`,
|
Example: ` # Run pre-installation checks
|
||||||
|
check --pre
|
||||||
|
|
||||||
|
# Run installation checks
|
||||||
|
check
|
||||||
|
`,
|
||||||
RunE: runCheckCmd,
|
RunE: runCheckCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +43,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
logAction("starting verification")
|
logAction("checking prerequisites")
|
||||||
checkFailed := false
|
checkFailed := false
|
||||||
if !sshCheck() {
|
if !sshCheck() {
|
||||||
checkFailed = true
|
checkFailed = true
|
||||||
@@ -51,18 +57,21 @@ func runCheckCmd(cmd *cobra.Command, args []string) error {
|
|||||||
checkFailed = true
|
checkFailed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if checkPre {
|
|
||||||
if checkFailed {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
logSuccess("all prerequisites checks passed")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !kubernetesCheck(">=1.14.0") {
|
if !kubernetesCheck(">=1.14.0") {
|
||||||
checkFailed = true
|
checkFailed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if checkPre {
|
||||||
|
if checkFailed {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
logSuccess("prerequisites checks passed")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !componentsCheck() {
|
||||||
|
checkFailed = true
|
||||||
|
}
|
||||||
if checkFailed {
|
if checkFailed {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
@@ -188,3 +197,19 @@ func kubernetesCheck(version string) bool {
|
|||||||
logSuccess("kubernetes %s %s", v.String(), version)
|
logSuccess("kubernetes %s %s", v.String(), version)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func componentsCheck() bool {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
for _, deployment := range components {
|
||||||
|
command := fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
||||||
|
namespace, deployment, timeout.String())
|
||||||
|
if output, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
|
||||||
|
logFailure("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
|
||||||
|
} else {
|
||||||
|
logSuccess("%s is healthy", deployment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,9 +15,17 @@ var installCmd = &cobra.Command{
|
|||||||
Use: "install",
|
Use: "install",
|
||||||
Short: "Install the toolkit components",
|
Short: "Install the toolkit components",
|
||||||
Long: `
|
Long: `
|
||||||
The install command deploys the toolkit components
|
The install command deploys the toolkit components in the specified namespace.
|
||||||
on the configured Kubernetes cluster in ~/.kube/config`,
|
If a previous version is installed, then an in-place upgrade will be performed.`,
|
||||||
Example: ` install --version=master --namespace=gitops-systems`,
|
Example: ` # Install the latest version in the gitops-systems namespace
|
||||||
|
install --version=master --namespace=gitops-systems
|
||||||
|
|
||||||
|
# Dry-run install for a specific version and a series of components
|
||||||
|
install --dry-run --version=0.0.1 --components="source-controller,kustomize-controller"
|
||||||
|
|
||||||
|
# Dry-run install with manifests preview
|
||||||
|
install --dry-run --verbose
|
||||||
|
`,
|
||||||
RunE: installCmdRun,
|
RunE: installCmdRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +65,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
logAction("generating install manifests")
|
logAction("generating install manifests")
|
||||||
if kustomizePath == "" {
|
if kustomizePath == "" {
|
||||||
err = genInstallManifests(installVersion, namespace, tmpDir)
|
err = genInstallManifests(installVersion, namespace, components, tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("install failed: %w", err)
|
return fmt.Errorf("install failed: %w", err)
|
||||||
}
|
}
|
||||||
@@ -103,7 +111,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logAction("verifying installation")
|
logAction("verifying installation")
|
||||||
for _, deployment := range []string{"source-controller", "kustomize-controller"} {
|
for _, deployment := range components {
|
||||||
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
||||||
namespace, deployment, timeout.String())
|
namespace, deployment, timeout.String())
|
||||||
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
|
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
|
||||||
@@ -138,6 +146,7 @@ fieldSpecs:
|
|||||||
`
|
`
|
||||||
|
|
||||||
var kustomizationTmpl = `---
|
var kustomizationTmpl = `---
|
||||||
|
{{- $version := .Version }}
|
||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
namespace: {{.Namespace}}
|
namespace: {{.Namespace}}
|
||||||
@@ -146,9 +155,10 @@ transformers:
|
|||||||
resources:
|
resources:
|
||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- roles
|
- roles
|
||||||
- github.com/fluxcd/toolkit/manifests/bases/source-controller?ref={{.Version}}
|
- github.com/fluxcd/toolkit/manifests/policies?ref={{$version}}
|
||||||
- github.com/fluxcd/toolkit/manifests/bases/kustomize-controller?ref={{.Version}}
|
{{- range .Components }}
|
||||||
- github.com/fluxcd/toolkit/manifests/policies?ref={{.Version}}
|
- github.com/fluxcd/toolkit/manifests/bases/{{.}}?ref={{$version}}
|
||||||
|
{{- end }}
|
||||||
`
|
`
|
||||||
|
|
||||||
var kustomizationRolesTmpl = `---
|
var kustomizationRolesTmpl = `---
|
||||||
@@ -159,13 +169,15 @@ resources:
|
|||||||
nameSuffix: -{{.Namespace}}
|
nameSuffix: -{{.Namespace}}
|
||||||
`
|
`
|
||||||
|
|
||||||
func genInstallManifests(ver, ns, tmpDir string) error {
|
func genInstallManifests(version string, namespace string, components []string, tmpDir string) error {
|
||||||
model := struct {
|
model := struct {
|
||||||
Version string
|
Version string
|
||||||
Namespace string
|
Namespace string
|
||||||
|
Components []string
|
||||||
}{
|
}{
|
||||||
Version: ver,
|
Version: version,
|
||||||
Namespace: ns,
|
Namespace: namespace,
|
||||||
|
Components: components,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil {
|
if err := utils.execTemplate(model, namespaceTmpl, path.Join(tmpDir, "namespace.yaml")); err != nil {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ var (
|
|||||||
namespace string
|
namespace string
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
verbose bool
|
verbose bool
|
||||||
|
components []string
|
||||||
utils Utils
|
utils Utils
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,6 +39,9 @@ func init() {
|
|||||||
"timeout for this operation")
|
"timeout for this operation")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
|
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "", false,
|
||||||
"print generated objects")
|
"print generated objects")
|
||||||
|
rootCmd.PersistentFlags().StringSliceVar(&components, "components",
|
||||||
|
[]string{"source-controller", "kustomize-controller"},
|
||||||
|
"list of components, accepts comma-separated values")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -13,8 +13,13 @@ var uninstallCmd = &cobra.Command{
|
|||||||
Short: "Uninstall the toolkit components",
|
Short: "Uninstall the toolkit components",
|
||||||
Long: `
|
Long: `
|
||||||
The uninstall command removes the namespace, cluster roles,
|
The uninstall command removes the namespace, cluster roles,
|
||||||
cluster role bindings and CRDs`,
|
cluster role bindings and CRDs.`,
|
||||||
Example: ` uninstall --namespace=gitops-system --crds --dry-run`,
|
Example: ` # Dry-run uninstall of all components
|
||||||
|
uninstall --dry-run --namespace=gitops-system
|
||||||
|
|
||||||
|
# Uninstall all components and custom resource definitions
|
||||||
|
uninstall --crds --namespace=gitops-system
|
||||||
|
`,
|
||||||
RunE: uninstallCmdRun,
|
RunE: uninstallCmdRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ func (*Utils) execCommand(ctx context.Context, mode ExecMode, command string) (s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mode == ModeCapture {
|
if mode == ModeCapture {
|
||||||
if output, err := c.CombinedOutput(); err != nil {
|
c.Stdout = &stdoutBuf
|
||||||
return "", err
|
c.Stderr = &stderrBuf
|
||||||
|
if err := c.Run(); err != nil {
|
||||||
|
return stderrBuf.String(), err
|
||||||
} else {
|
} else {
|
||||||
return string(output), nil
|
return stdoutBuf.String(), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user