Skip to content

Commit

Permalink
fix: check if resource exists in update cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
lizzy-0323 committed Nov 18, 2024
1 parent c6fae07 commit 5d37b30
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 48 deletions.
8 changes: 4 additions & 4 deletions internal/cli/cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ func NewCmd() *cobra.Command {
logger := utils.GetDefaultLoggerInstance()
cmd := &cobra.Command{
Use: "install <component>",
Short: "Command for ob-operator and components installation",
Long: `Command for ob-operator and components installation.
Short: "Command for ob-operator and other components installation",
Long: `Command for ob-operator and other components installation.
Currently support:
- ob-operator: A Kubernetes operator that simplifies the deployment and management of OceanBase cluster and related resources on Kubernetes.
- ob-dashboard: A web application that provides resource management capabilities.
- local-path-provisioner: Provides a way for the Kubernetes users to utilize the local storage in each node, Storage of OceanBase cluster relies on it, which should be installed beforehand.
- cert-manager: Creates TLS certificates for workloads in Kubernetes and renews the certificates before they expire, ob-operator relies on it for certificate management, which should be installed beforehand.
if not specified, install ob-operator and ob-dashboard by default`,
if not specified, install ob-operator and ob-dashboard by default, and cert-manager if it is not found in cluster.`,
PreRunE: o.Parse,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -46,7 +46,7 @@ if not specified, install ob-operator and ob-dashboard by default`,
if err := o.Install(component, version); err != nil {
logger.Fatalln(err)
} else {
logger.Printf("%s install successfully", component)
logger.Printf("%s install successfully\n", component)
}
}
},
Expand Down
22 changes: 14 additions & 8 deletions internal/cli/cmd/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func NewCmd() *cobra.Command {
logger := utils.GetDefaultLoggerInstance()
cmd := &cobra.Command{
Use: "update <component>",
Short: "Command for ob-operator and components update",
Long: `Command for ob-operator and components update.
Short: "Command for ob-operator and other components update",
Long: `Command for ob-operator and other components update.
Currently support:
- ob-operator: A Kubernetes operator that simplifies the deployment and management of OceanBase cluster and related resources on Kubernetes.
Expand All @@ -39,16 +39,22 @@ if not specified, update ob-operator and ob-dashboard by default`,
PreRunE: o.Parse,
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
logger.Println("update ob-operator and ob-dashboard by default")
}
componentCount := 0
for component, version := range o.Components {
if err := o.Install(component, version); err != nil {
logger.Fatalln(err)
if utils.CheckIfComponentExists(component) {
componentCount++
if err := o.Install(component, version); err != nil {
logger.Fatalln(err)
} else {
logger.Printf("%s update successfully\n", component)
}
} else {
logger.Printf("%s update successfully", component)
logger.Printf("Component %s is not found\n", component)
}
}
if componentCount == 0 {
logger.Println("No components to update")
}
},
}
return cmd
Expand Down
36 changes: 3 additions & 33 deletions internal/cli/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ See the Mulan PSL v2 for more details.
package install

import (
"bytes"
"fmt"
"os"
"os/exec"
Expand Down Expand Up @@ -46,7 +45,7 @@ func (o *InstallOptions) AddFlags(cmd *cobra.Command) {
func (o *InstallOptions) Parse(_ *cobra.Command, args []string) error {
// if not specified, use default config
if len(args) == 0 {
defaultComponents := o.getDefaultComponents()
defaultComponents := o.GetDefaultComponents()
// update Components to default config
o.Components = defaultComponents
return nil
Expand Down Expand Up @@ -104,39 +103,10 @@ func (o *InstallOptions) buildCmd(component, version string) (*exec.Cmd, error)
return cmd, nil
}

// checkCertManager checks cert-manager in the environment
func checkCertManager() bool {
cmd := exec.Command("kubectl", "get", "crds", "-o", "name", "|", "grep", "cert-manager")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return false
}

// Check if the output contains cert-manager resources
expectedResources := []string{
"challenges.acme.cert-manager.io",
"orders.acme.cert-manager.io",
"certificaterequests.cert-manager.io",
"certificates.cert-manager.io",
"clusterissuers.cert-manager.io",
"issuers.cert-manager.io",
}

for _, resource := range expectedResources {
if !bytes.Contains(out.Bytes(), []byte(resource)) {
return false
}
}

return true
}

func (o *InstallOptions) getDefaultComponents() map[string]string {
func (o *InstallOptions) GetDefaultComponents() map[string]string {
defaultComponents := make(map[string]string) // Initialize the map
var componentsList []string
if !checkCertManager() {
if !utils.CheckIfComponentExists("cert-manager") {
componentsList = []string{"cert-manager", "ob-operator", "ob-dashboard"}
} else {
componentsList = []string{"ob-operator", "ob-dashboard"}
Expand Down
11 changes: 8 additions & 3 deletions internal/cli/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ func NewUpdateOptions() *UpdateOptions {
}

func (o *UpdateOptions) Parse(_ *cobra.Command, args []string) error {
// if not specified, use default config
if len(args) == 0 {
defaultComponents := o.GetDefaultComponents()

Check failure on line 37 in internal/cli/update/update.go

View workflow job for this annotation

GitHub Actions / lint

o.GetDefaultComponents undefined (type *UpdateOptions has no field or method GetDefaultComponents) (typecheck)
// update Components to default config
o.Components = defaultComponents

Check failure on line 39 in internal/cli/update/update.go

View workflow job for this annotation

GitHub Actions / lint

o.Components undefined (type *UpdateOptions has no field or method Components) (typecheck)
return nil
}
name := args[0]
if _, ok := o.Components[name]; !ok {
return fmt.Errorf("%s update not supported", name)
if v, ok := o.Components[name]; ok {

Check failure on line 43 in internal/cli/update/update.go

View workflow job for this annotation

GitHub Actions / lint

o.Components undefined (type *UpdateOptions has no field or method Components) (typecheck)
o.Components = map[string]string{name: v}

Check failure on line 44 in internal/cli/update/update.go

View workflow job for this annotation

GitHub Actions / lint

o.Components undefined (type *UpdateOptions has no field or method Components) (typecheck)
return nil
}
return nil
return fmt.Errorf("component %s is not supported", name)
}
72 changes: 72 additions & 0 deletions internal/cli/utils/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,51 @@ See the Mulan PSL v2 for more details.
package utils

import (
"bytes"
"fmt"
"os/exec"

apitypes "github.com/oceanbase/ob-operator/api/types"
"github.com/oceanbase/ob-operator/api/v1alpha1"
clusterstatus "github.com/oceanbase/ob-operator/internal/const/status/obcluster"
"github.com/oceanbase/ob-operator/internal/const/status/tenantstatus"
)

var (
operatorCheckCmd = "kubectl get crds -A -o name | grep oceanbase.oceanbase.com"
certManagerCheckCmd = "kubectl get crds -o name | grep cert-manager"
dashboardCheckCmd = "helm list | grep oceanbase-dashboard"
localPathProvisionerCheckCmd = "kubectl get deployment -A | grep local-path-provisioner"
)

var (
// Define the resources to check for each command
certManagerResources = []string{
"challenges.acme.cert-manager.io",
"orders.acme.cert-manager.io",
"certificaterequests.cert-manager.io",
"certificates.cert-manager.io",
"clusterissuers.cert-manager.io",
"issuers.cert-manager.io",
}

operatorResources = []string{
"obparameters.oceanbase.oceanbase.com",
"observers.oceanbase.oceanbase.com",
"obclusters.oceanbase.oceanbase.com",
"obtenantbackups.oceanbase.oceanbase.com",
"obtenantrestores.oceanbase.oceanbase.com",
"obzones.oceanbase.oceanbase.com",
"obtenants.oceanbase.oceanbase.com",
"obtenantoperations.oceanbase.oceanbase.com",
"obtenantbackuppolicies.oceanbase.oceanbase.com",
}

dashboardResources = "oceanbase-dashboard"

localPathProvisionerResources = "local-path-provisioner"
)

// CheckTenantStatus checks running status of obtenant
func CheckTenantStatus(tenant *v1alpha1.OBTenant) error {
if tenant.Status.Status != tenantstatus.Running {
Expand Down Expand Up @@ -53,3 +90,38 @@ func CheckTenantRole(tenant *v1alpha1.OBTenant, role apitypes.TenantRole) error
}
return nil
}

// CheckIfComponentExists checks if component exists in the environment
func CheckIfComponentExists(component string) bool {
switch component {
case "cert-manager":
return checkIfResourceExists(certManagerCheckCmd, certManagerResources...)
case "ob-operator":
return checkIfResourceExists(operatorCheckCmd, operatorResources...)
case "ob-dashboard":
return checkIfResourceExists(dashboardCheckCmd, dashboardResources)
case "local-path-provisioner":
return checkIfResourceExists(localPathProvisionerCheckCmd, localPathProvisionerResources)
default:
return false
}
}

// checkIfResourceExists checks if the resource exists in the environment
func checkIfResourceExists(checkCmd string, resourceList ...string) bool {
cmd := exec.Command("sh", "-c", checkCmd)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()

if err != nil {
return false
}

for _, resource := range resourceList {
if !bytes.Contains(out.Bytes(), []byte(resource)) {
return false
}
}
return true
}

0 comments on commit 5d37b30

Please sign in to comment.