generated from LinuxSuRen/.github
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support to exec a component (#63)
* Add support to exec a componenet * Use github.com/stretchr/testify/assert
- Loading branch information
1 parent
623dfeb
commit 3d7b2f3
Showing
8 changed files
with
296 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package common | ||
|
||
import "github.com/spf13/cobra" | ||
|
||
// NoFileCompletion avoid completion with files | ||
func NoFileCompletion(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { | ||
return nil, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
|
||
// ArrayCompletion return a completion which base on an array | ||
func ArrayCompletion(array ...string) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return array, cobra.ShellCompDirectiveNoFileComp | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package component | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/linuxsuren/ks/kubectl-plugin/common" | ||
kstypes "github.com/linuxsuren/ks/kubectl-plugin/types" | ||
"github.com/spf13/cobra" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/client-go/dynamic" | ||
"strconv" | ||
) | ||
|
||
// EnableOption is the option for component enable command | ||
type EnableOption struct { | ||
Option | ||
|
||
Edit bool | ||
Toggle bool | ||
} | ||
|
||
func getAvailableComponents() func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { | ||
return common.ArrayCompletion("devops", "alerting", "auditing", "events", "logging", "metrics_server", "networkpolicy", "notification", "openpitrix", "servicemesh") | ||
} | ||
|
||
// NewComponentEnableCmd returns a command to enable (or disable) a component by name | ||
func NewComponentEnableCmd(client dynamic.Interface) (cmd *cobra.Command) { | ||
opt := &EnableOption{ | ||
Option: Option{ | ||
Client: client, | ||
}, | ||
} | ||
|
||
availableComs := getAvailableComponents() | ||
|
||
cmd = &cobra.Command{ | ||
Use: "enable", | ||
Short: "Enable or disable the specific KubeSphere component", | ||
PreRunE: opt.enablePreRunE, | ||
ValidArgsFunction: availableComs, | ||
RunE: opt.enableRunE, | ||
} | ||
|
||
flags := cmd.Flags() | ||
flags.BoolVarP(&opt.Edit, "edit", "e", false, | ||
"Indicate if you want to edit it instead of enable/disable a specified one. This flag will make others not work.") | ||
flags.BoolVarP(&opt.Toggle, "toggle", "t", false, | ||
"Indicate if you want to disable a component") | ||
flags.StringVarP(&opt.Name, "name", "n", "", | ||
"The name of target component which you want to enable/disable. Please provide option --sonarqube if you want to enable SonarQube.") | ||
flags.StringVarP(&opt.SonarQube, "sonarqube", "", "", | ||
"The SonarQube URL") | ||
flags.StringVarP(&opt.SonarQube, "sonar", "", "", | ||
"The SonarQube URL") | ||
flags.StringVarP(&opt.SonarQubeToken, "sonarqube-token", "", "", | ||
"The token of SonarQube") | ||
|
||
_ = cmd.RegisterFlagCompletionFunc("name", availableComs) | ||
|
||
// these are aliased options | ||
_ = flags.MarkHidden("sonar") | ||
return | ||
} | ||
|
||
func (o *EnableOption) enablePreRunE(cmd *cobra.Command, args []string) (err error) { | ||
if o.Edit { | ||
return | ||
} | ||
|
||
return o.componentNameCheck(cmd, args) | ||
} | ||
|
||
func (o *EnableOption) enableRunE(cmd *cobra.Command, args []string) (err error) { | ||
if o.Edit { | ||
err = common.UpdateWithEditor(kstypes.GetClusterConfiguration(), "kubesphere-system", "ks-installer", o.Client) | ||
} else { | ||
enabled := strconv.FormatBool(!o.Toggle) | ||
ns, name := "kubesphere-system", "ks-installer" | ||
var patchTarget string | ||
switch o.Name { | ||
case "devops", "alerting", "auditing", "events", "logging", "metrics_server", "networkpolicy", "notification", "openpitrix", "servicemesh": | ||
patchTarget = o.Name | ||
case "sonarqube", "sonar": | ||
if o.SonarQube == "" || o.SonarQubeToken == "" { | ||
err = fmt.Errorf("SonarQube or token is empty, please provide --sonarqube") | ||
} else { | ||
name = "ks-console-config" | ||
err = integrateSonarQube(o.Client, ns, name, o.SonarQube, o.SonarQubeToken) | ||
} | ||
return | ||
default: | ||
err = fmt.Errorf("not support [%s] yet", o.Name) | ||
return | ||
} | ||
|
||
patch := fmt.Sprintf(`[{"op": "replace", "path": "/spec/%s/enabled", "value": %s}]`, patchTarget, enabled) | ||
ctx := context.TODO() | ||
_, err = o.Client.Resource(kstypes.GetClusterConfiguration()).Namespace(ns).Patch(ctx, | ||
name, types.JSONPatchType, | ||
[]byte(patch), | ||
metav1.PatchOptions{}) | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package component | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/linuxsuren/ks/kubectl-plugin/common" | ||
kstypes "github.com/linuxsuren/ks/kubectl-plugin/types" | ||
"github.com/spf13/cobra" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
"k8s.io/client-go/dynamic" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
"syscall" | ||
) | ||
|
||
func newComponentsExecCmd(client dynamic.Interface) (cmd *cobra.Command) { | ||
availableComs := common.ArrayCompletion("jenkins", "apiserver") | ||
|
||
cmd = &cobra.Command{ | ||
Use: "exec", | ||
Short: "Execute a command in a container.", | ||
Long: `Execute a command in a container. | ||
This command is similar with kubectl exec, the only difference is that you don't need to type the fullname'`, | ||
ValidArgsFunction: availableComs, | ||
Args: cobra.MinimumNArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) (err error) { | ||
var kubectl string | ||
if kubectl, err = exec.LookPath("kubectl"); err != nil { | ||
return | ||
} | ||
|
||
switch args[0] { | ||
case "jenkins": | ||
var jenkinsPodName string | ||
var list *unstructured.UnstructuredList | ||
if list, err = client.Resource(kstypes.GetPodSchema()).Namespace("kubesphere-devops-system").List( | ||
context.TODO(), metav1.ListOptions{}); err == nil { | ||
for _, item := range list.Items { | ||
if strings.HasPrefix(item.GetName(), "ks-jenkins") { | ||
jenkinsPodName = item.GetName() | ||
} | ||
} | ||
} else { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
if jenkinsPodName == "" { | ||
err = fmt.Errorf("cannot found ks-jenkins pod") | ||
} else { | ||
err = syscall.Exec(kubectl, []string{"kubectl", "-n", "kubesphere-devops-system", "exec", "-it", jenkinsPodName, "bash"}, os.Environ()) | ||
} | ||
case "apiserver": | ||
var apiserverPodName string | ||
var list *unstructured.UnstructuredList | ||
if list, err = client.Resource(kstypes.GetPodSchema()).Namespace("kubesphere-system").List( | ||
context.TODO(), metav1.ListOptions{}); err == nil { | ||
for _, item := range list.Items { | ||
if strings.HasPrefix(item.GetName(), "ks-apiserver") { | ||
apiserverPodName = item.GetName() | ||
} | ||
} | ||
} else { | ||
fmt.Println(err) | ||
return | ||
} | ||
|
||
if apiserverPodName == "" { | ||
err = fmt.Errorf("cannot found ks-jenkins pod") | ||
} else { | ||
err = syscall.Exec(kubectl, []string{"kubectl", "-n", "kubesphere-system", "exec", "-it", apiserverPodName, "sh"}, os.Environ()) | ||
} | ||
} | ||
return | ||
}, | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.