pull file
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
Close Stale Issues / close_stale_issues (push) Has been cancelled
repo-sync / repo-sync (push) Has been cancelled
auto-deploy-tencent-scf / pre-check (push) Has been cancelled
auto-deploy-tencent-scf / deploy serverless (push) Has been cancelled
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
Close Stale Issues / close_stale_issues (push) Has been cancelled
repo-sync / repo-sync (push) Has been cancelled
auto-deploy-tencent-scf / pre-check (push) Has been cancelled
auto-deploy-tencent-scf / deploy serverless (push) Has been cancelled
This commit is contained in:
39
krew/pkg/cmd/cmd.go
Normal file
39
krew/pkg/cmd/cmd.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
)
|
||||
|
||||
const (
|
||||
biliproDesc = `Manage and deploy bilibili pro tools on k8s`
|
||||
kubeconfig = "kubeconfig"
|
||||
)
|
||||
|
||||
var (
|
||||
confPath string
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "bilipro",
|
||||
Long: biliproDesc,
|
||||
SilenceUsage: true,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVar(&confPath, kubeconfig, "", "Custom kubeconfig path")
|
||||
|
||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||
}
|
||||
|
||||
// New creates a new root command for kubectl-bilipro
|
||||
func NewExecutor(streams genericclioptions.IOStreams) *cobra.Command {
|
||||
cobra.EnableCommandSorting = false
|
||||
rootCmd.AddCommand(newInitCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
|
||||
// If you want to update, just init again
|
||||
rootCmd.AddCommand(newGetCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
|
||||
rootCmd.AddCommand(newDeleteCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
|
||||
rootCmd.AddCommand(newVersionCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr()))
|
||||
return rootCmd
|
||||
}
|
||||
130
krew/pkg/cmd/delete.go
Normal file
130
krew/pkg/cmd/delete.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options"
|
||||
helper "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
deleteDesc = `
|
||||
'delete' command delete bilibilipro tool.`
|
||||
deleteExample = ` kubectl bilipro delete <--name deployment_name>`
|
||||
)
|
||||
|
||||
type deleteCmd struct {
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
output bool
|
||||
deployOpts options.DeployOptions
|
||||
}
|
||||
|
||||
func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
|
||||
o := &deleteCmd{out: out, errOut: errOut}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete bilibilipro",
|
||||
Long: deleteDesc,
|
||||
Example: deleteExample,
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := o.run(out)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
fmt.Println("bilibili tool is removed from your cluster")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
f := cmd.Flags()
|
||||
f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request")
|
||||
f.StringVarP(&o.deployOpts.Name, "name", "", "bilibilipro", "name of deployment to delete")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (o *deleteCmd) run(writer io.Writer) error {
|
||||
inDiskSys, err := helper.GetResourceFileSys()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove namespace files lastly
|
||||
resources := []string{"base/bilibiliPro/deployment.yaml"}
|
||||
|
||||
// write the kustomization file
|
||||
|
||||
kustomizationYaml := types.Kustomization{
|
||||
TypeMeta: types.TypeMeta{
|
||||
Kind: "Kustomization",
|
||||
APIVersion: "kustomize.config.k8s.io/v1beta1",
|
||||
},
|
||||
Resources: resources,
|
||||
}
|
||||
|
||||
if o.deployOpts.Namespace != "" {
|
||||
kustomizationYaml.Namespace = o.deployOpts.Namespace
|
||||
}
|
||||
|
||||
// Compile the kustomization to a file and create on the in memory filesystem
|
||||
kustYaml, err := yaml.Marshal(kustomizationYaml)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
kustFile, err := inDiskSys.Create("./bilipro/kustomization.yaml")
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
_, err = kustFile.Write(kustYaml)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
// kustomize build the target location
|
||||
k := krusty.MakeKustomizer(
|
||||
krusty.MakeDefaultOptions(),
|
||||
)
|
||||
|
||||
m, err := k.Run(inDiskSys, "./bilipro")
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
yml, err := m.AsYaml()
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
if o.output {
|
||||
_, err = writer.Write(yml)
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
// do kubectl delete
|
||||
cmd := exec.Command("kubectl", "delete", "-f", "-")
|
||||
|
||||
if err := helper.Run(cmd, strings.NewReader(string(yml))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete the namespace
|
||||
cmd = exec.Command("kubectl", "delete", "ns", o.deployOpts.Namespace)
|
||||
if err := helper.Run(cmd, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
61
krew/pkg/cmd/get.go
Normal file
61
krew/pkg/cmd/get.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
|
||||
"github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options"
|
||||
helper "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
getDesc = `
|
||||
'get' command get bilibilipro tool deployment.`
|
||||
getExample = ` kubectl bilipro get <--name deployment_name --namespace namespace_name>`
|
||||
)
|
||||
|
||||
type getCmd struct {
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
|
||||
deployOpts options.DeployOptions
|
||||
}
|
||||
|
||||
func newGetCmd(out io.Writer, errOut io.Writer) *cobra.Command {
|
||||
o := &getCmd{out: out, errOut: errOut}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get bilibilipro",
|
||||
Long: getDesc,
|
||||
Example: getExample,
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
err := o.run(out)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
f := cmd.Flags()
|
||||
f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request")
|
||||
f.StringVarP(&o.deployOpts.Name, "name", "", "bilibilipro", "name of deployment to get")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (o *getCmd) run(writer io.Writer) error {
|
||||
// do kubectl get
|
||||
cmd := exec.Command("kubectl", "get", "deploy", o.deployOpts.Name, "-n", o.deployOpts.Namespace)
|
||||
|
||||
if err := helper.Run(cmd, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
286
krew/pkg/cmd/init.go
Normal file
286
krew/pkg/cmd/init.go
Normal file
@@ -0,0 +1,286 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options"
|
||||
helper "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/utils"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
)
|
||||
|
||||
const (
|
||||
initDesc = `
|
||||
'init' command creates BilibiliPro deployment along with all the dependencies.`
|
||||
initExample = ` kubectl bilipro init --config <config-file>`
|
||||
)
|
||||
|
||||
type initCmd struct {
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
output bool
|
||||
login bool
|
||||
deployOpts options.DeployOptions
|
||||
}
|
||||
|
||||
func newInitCmd(out io.Writer, errOut io.Writer) *cobra.Command {
|
||||
o := &initCmd{out: out, errOut: errOut}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "Initialize bilipro",
|
||||
Long: initDesc,
|
||||
Example: initExample,
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := o.run(out)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
f := cmd.Flags()
|
||||
f.StringVarP(&o.deployOpts.Image, "image", "i", "zai7lou/bilibili_tool_pro:2.0.1", "bilibilipro image")
|
||||
f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request")
|
||||
f.StringVar(&o.deployOpts.ImagePullSecret, "image-pull-secret", "", "image pull secret to be used for pulling bilibilipro image")
|
||||
f.StringVarP(&o.deployOpts.ConfigFilePath, "config", "c", "", "the config file contanis the environment variables")
|
||||
f.BoolVarP(&o.output, "output", "o", false, "dry run this command and generate requisite yaml")
|
||||
f.BoolVarP(&o.login, "login", "l", false, "scan QR login code")
|
||||
return cmd
|
||||
}
|
||||
|
||||
type opStr struct {
|
||||
Op string `json:"op"`
|
||||
Path string `json:"path"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type opInterface struct {
|
||||
Op string `json:"op"`
|
||||
Path string `json:"path"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type normalEnvVars struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// run initializes local config and installs BiliBiliPro tool to Kubernetes Cluster.
|
||||
func (o *initCmd) run(writer io.Writer) error {
|
||||
inDiskSys, err := helper.GetResourceFileSys()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: All about paths are a little bit tricky should give it more thoughts
|
||||
|
||||
fmt.Println("Creating the kustomization file")
|
||||
// if the bilibili tool is deployed under system/pre-defined namespace, ignore the namespace file
|
||||
var resources []string // nolint: go-staticcheck
|
||||
if o.deployOpts.Namespace == "default" || o.deployOpts.Namespace == "kube-system" || o.deployOpts.Namespace == "kube-public" {
|
||||
resources = []string{"base/bilibiliPro/deployment.yaml"}
|
||||
} else {
|
||||
resources = []string{"base/ns/namespace.yaml", "base/bilibiliPro/deployment.yaml"}
|
||||
}
|
||||
|
||||
// write the kustomization file
|
||||
kustomizationYaml := types.Kustomization{
|
||||
TypeMeta: types.TypeMeta{
|
||||
Kind: "Kustomization",
|
||||
APIVersion: "kustomize.config.k8s.io/v1beta1",
|
||||
},
|
||||
Resources: resources,
|
||||
PatchesJson6902: []types.Patch{},
|
||||
}
|
||||
|
||||
var deployDepPatches []interface{}
|
||||
// create patches for the supplied arguments
|
||||
if o.deployOpts.Image != "" {
|
||||
deployDepPatches = append(deployDepPatches, opStr{
|
||||
Op: "replace",
|
||||
Path: "/spec/template/spec/containers/0/image",
|
||||
Value: o.deployOpts.Image,
|
||||
})
|
||||
}
|
||||
// create patches for the env
|
||||
content, err := os.ReadFile(o.deployOpts.ConfigFilePath)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.FILE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
envs := []normalEnvVars{}
|
||||
err = yaml.Unmarshal(content, &envs)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
deployDepPatches = append(deployDepPatches, opInterface{
|
||||
Op: "add",
|
||||
Path: "/spec/template/spec/containers/0/env",
|
||||
Value: envs,
|
||||
})
|
||||
|
||||
if o.deployOpts.ImagePullSecret != "" {
|
||||
deployDepPatches = append(deployDepPatches, opInterface{
|
||||
Op: "add",
|
||||
Path: "/spec/template/spec/imagePullSecrets",
|
||||
Value: []corev1.LocalObjectReference{{Name: o.deployOpts.ImagePullSecret}},
|
||||
})
|
||||
}
|
||||
|
||||
// attach the patches to the kustomization file
|
||||
if len(deployDepPatches) > 0 {
|
||||
kustomizationYaml.PatchesJson6902 = append(kustomizationYaml.PatchesJson6902, types.Patch{
|
||||
Patch: o.serializeJSONPatchOps(deployDepPatches),
|
||||
Target: &types.Selector{
|
||||
ResId: resid.ResId{
|
||||
Gvk: resid.Gvk{
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
Name: "bilibilipro",
|
||||
Namespace: o.deployOpts.Namespace,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Not deploying in kube-* namespace
|
||||
if o.deployOpts.Namespace == "kube-system" || o.deployOpts.Namespace == "kube-public" {
|
||||
fmt.Println("better not deployed under system namesapce")
|
||||
}
|
||||
|
||||
if o.deployOpts.Namespace != "" {
|
||||
kustomizationYaml.Namespace = o.deployOpts.Namespace
|
||||
}
|
||||
// Compile the kustomization to a file and create on the in memory filesystem
|
||||
kustYaml, err := yaml.Marshal(kustomizationYaml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kustFile, err := inDiskSys.Create("./bilipro/kustomization.yaml")
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
_, err = kustFile.Write(kustYaml)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
// kustomize build the target location
|
||||
k := krusty.MakeKustomizer(
|
||||
krusty.MakeDefaultOptions(),
|
||||
)
|
||||
|
||||
m, err := k.Run(inDiskSys, "./bilipro")
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
yml, err := m.AsYaml()
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
|
||||
if o.output {
|
||||
_, err = writer.Write(yml)
|
||||
if err != nil {
|
||||
return helper.GenErrorMsg(helper.TEMPLATE_ERROR, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Applying the kustomization file")
|
||||
// do kubectl apply
|
||||
// make sure kubectl is under your PATH
|
||||
cmd := exec.Command("kubectl", "apply", "-f", "-")
|
||||
|
||||
if err := helper.Run(cmd, strings.NewReader(string(yml))); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if there is login required, exectue the login command as the last step
|
||||
if o.login {
|
||||
fmt.Println("please login...")
|
||||
client, _, err := helper.GetK8sClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the pod name
|
||||
podName, err := helper.GetBiliName(client, o.deployOpts.Namespace, "bilibilipro")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("wait for the deployment to be ready")
|
||||
// Wait for the deployment ready
|
||||
checkCmdArgs := []string{
|
||||
"rollout",
|
||||
"status",
|
||||
"deployment/bilibilipro",
|
||||
"-n",
|
||||
o.deployOpts.Namespace,
|
||||
}
|
||||
checkCmd := exec.Command("kubectl", checkCmdArgs...)
|
||||
|
||||
for {
|
||||
if err := checkCmd.Start(); err != nil {
|
||||
fmt.Printf("deployment is not ready yet, current status: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
err := checkCmd.Wait()
|
||||
if err == nil {
|
||||
fmt.Printf("deployment is ready\n")
|
||||
break
|
||||
}
|
||||
fmt.Printf("deployment is not ready yet, current status: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Println("please scan the QR code")
|
||||
// Exec the login command
|
||||
args := []string{
|
||||
"exec",
|
||||
podName,
|
||||
"-n",
|
||||
o.deployOpts.Namespace,
|
||||
"--",
|
||||
"dotnet",
|
||||
"Ray.BiliBiliTool.Console.dll",
|
||||
"--runTasks=Login",
|
||||
}
|
||||
cmd := exec.Command("kubectl", args...)
|
||||
|
||||
if err := helper.Run(cmd, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *initCmd) serializeJSONPatchOps(jp []interface{}) string {
|
||||
jpJSON, _ := json.Marshal(jp)
|
||||
return string(jpJSON)
|
||||
}
|
||||
50
krew/pkg/cmd/version.go
Normal file
50
krew/pkg/cmd/version.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// version provides the version of this plugin
|
||||
var version = "NO.VERSION"
|
||||
|
||||
const (
|
||||
versionDesc = `
|
||||
'version' command displays the kubectl plugin version.`
|
||||
versionExample = ` kubectl bilipro version`
|
||||
)
|
||||
|
||||
type versionCmd struct {
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
}
|
||||
|
||||
func newVersionCmd(out io.Writer, errOut io.Writer) *cobra.Command {
|
||||
o := &versionCmd{out: out, errOut: errOut}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Display plugin version",
|
||||
Long: versionDesc,
|
||||
Example: versionExample,
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := o.run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// run initializes local config and installs BilibiliPro Plugin to Kubernetes cluster.
|
||||
func (o *versionCmd) run() error {
|
||||
fmt.Println(version)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user