mirror of
https://github.com/rancher/k3k.git
synced 2026-08-19 04:16:16 +00:00
Flatten the cli structure, add docs generation in the Makefile and remove crds/Makefile
This commit is contained in:
@@ -9,10 +9,12 @@ CONTROLLER_TOOLS_VERSION ?= v0.14.0
|
||||
GINKGO_VERSION ?= v2.21.0
|
||||
ENVTEST_VERSION ?= latest
|
||||
ENVTEST_K8S_VERSION := 1.31.0
|
||||
CRD_REF_DOCS_VER ?= v0.1.0
|
||||
|
||||
GOLANGCI_LINT ?= go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
|
||||
CONTROLLER_GEN ?= go run sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
|
||||
GINKGO ?= go run github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION)
|
||||
CRD_REF_DOCS := go run github.com/elastic/crd-ref-docs@$(CRD_REF_DOCS_VER)
|
||||
|
||||
ENVTEST ?= go run sigs.k8s.io/controller-runtime/tools/setup-envtest@$(ENVTEST_VERSION)
|
||||
ENVTEST_DIR ?= $(shell pwd)/.envtest
|
||||
@@ -75,8 +77,9 @@ build-crds: ## Build the CRDs specs
|
||||
output:crd:dir=./charts/k3k/crds
|
||||
|
||||
.PHONY: docs
|
||||
docs: ## Build the CRDs docs
|
||||
$(MAKE) -C docs/crds
|
||||
docs: ## Build the CRDs and CLI docs
|
||||
$(CRD_REF_DOCS) --config=./docs/crds/config.yaml --renderer=markdown --source-path=./pkg/apis/k3k.io/v1alpha1 --output-path=./docs/crds/crd-docs.md
|
||||
@go run ./docs/cli/genclidoc.go
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Find any linting issues in the project
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package cluster
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func NewCommand() *cli.Command {
|
||||
func NewClusterCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "cluster",
|
||||
Usage: "cluster command",
|
||||
Subcommands: []*cli.Command{
|
||||
NewCreateCmd(),
|
||||
NewDeleteCmd(),
|
||||
NewClusterCreateCmd(),
|
||||
NewClusterDeleteCmd(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package cluster
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/k3k/cli/cmds"
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
|
||||
k3kcluster "github.com/rancher/k3k/pkg/controller/cluster"
|
||||
"github.com/rancher/k3k/pkg/controller/kubeconfig"
|
||||
@@ -18,9 +17,7 @@ import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/client-go/util/retry"
|
||||
@@ -28,13 +25,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(Scheme)
|
||||
_ = v1alpha1.AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
type CreateConfig struct {
|
||||
token string
|
||||
clusterCIDR string
|
||||
@@ -50,7 +40,7 @@ type CreateConfig struct {
|
||||
kubeconfigServerHost string
|
||||
}
|
||||
|
||||
func NewCreateCmd() *cli.Command {
|
||||
func NewClusterCreateCmd() *cli.Command {
|
||||
createConfig := &CreateConfig{}
|
||||
createFlags := NewCreateFlags(createConfig)
|
||||
|
||||
@@ -59,7 +49,7 @@ func NewCreateCmd() *cli.Command {
|
||||
Usage: "Create new cluster",
|
||||
UsageText: "k3kcli cluster create [command options] NAME",
|
||||
Action: createAction(createConfig),
|
||||
Flags: append(cmds.CommonFlags, createFlags...),
|
||||
Flags: append(CommonFlags, createFlags...),
|
||||
HideHelpCommand: true,
|
||||
}
|
||||
}
|
||||
@@ -77,7 +67,7 @@ func createAction(config *CreateConfig) cli.ActionFunc {
|
||||
return errors.New("invalid cluster name")
|
||||
}
|
||||
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", cmds.Kubeconfig)
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", Kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -97,8 +87,7 @@ func createAction(config *CreateConfig) cli.ActionFunc {
|
||||
|
||||
if config.token != "" {
|
||||
logrus.Infof("Creating cluster token secret")
|
||||
|
||||
obj := k3kcluster.TokenSecretObj(config.token, name, cmds.Namespace())
|
||||
obj := k3kcluster.TokenSecretObj(config.token, name, Namespace())
|
||||
if err := ctrlClient.Create(ctx, &obj); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -106,7 +95,7 @@ func createAction(config *CreateConfig) cli.ActionFunc {
|
||||
|
||||
logrus.Infof("Creating a new cluster [%s]", name)
|
||||
|
||||
cluster := newCluster(name, cmds.Namespace(), config)
|
||||
cluster := newCluster(name, Namespace(), config)
|
||||
|
||||
cluster.Spec.Expose = &v1alpha1.ExposeConfig{
|
||||
NodePort: &v1alpha1.NodePortConfig{},
|
||||
@@ -117,12 +106,10 @@ func createAction(config *CreateConfig) cli.ActionFunc {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
host := strings.Split(url.Host, ":")
|
||||
if config.kubeconfigServerHost != "" {
|
||||
host = []string{config.kubeconfigServerHost}
|
||||
}
|
||||
|
||||
cluster.Spec.TLSSANs = []string{host[0]}
|
||||
|
||||
if err := ctrlClient.Create(ctx, cluster); err != nil {
|
||||
@@ -147,7 +134,6 @@ func createAction(config *CreateConfig) cli.ActionFunc {
|
||||
cfg := kubeconfig.New()
|
||||
|
||||
var kubeconfig *clientcmdapi.Config
|
||||
|
||||
if err := retry.OnError(availableBackoff, apierrors.IsNotFound, func() error {
|
||||
kubeconfig, err = cfg.Extract(ctx, ctrlClient, cluster, host[0])
|
||||
return err
|
||||
@@ -203,7 +189,6 @@ func newCluster(name, namespace string, config *CreateConfig) *v1alpha1.Cluster
|
||||
if config.storageClassName == "" {
|
||||
cluster.Spec.Persistence.StorageClassName = nil
|
||||
}
|
||||
|
||||
if config.token != "" {
|
||||
cluster.Spec.TokenSecretRef = &v1.SecretReference{
|
||||
Name: k3kcluster.TokenSecretName(name),
|
||||
@@ -1,4 +1,4 @@
|
||||
package cluster
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -1,10 +1,9 @@
|
||||
package cluster
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/rancher/k3k/cli/cmds"
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
|
||||
k3kcluster "github.com/rancher/k3k/pkg/controller/cluster"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -14,13 +13,13 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func NewDeleteCmd() *cli.Command {
|
||||
func NewClusterDeleteCmd() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete an existing cluster",
|
||||
UsageText: "k3kcli cluster delete [command options] NAME",
|
||||
Action: delete,
|
||||
Flags: cmds.CommonFlags,
|
||||
Flags: CommonFlags,
|
||||
HideHelpCommand: true,
|
||||
}
|
||||
}
|
||||
@@ -37,7 +36,7 @@ func delete(clx *cli.Context) error {
|
||||
return errors.New("invalid cluster name")
|
||||
}
|
||||
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", cmds.Kubeconfig)
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", Kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -54,9 +53,8 @@ func delete(clx *cli.Context) error {
|
||||
cluster := v1alpha1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: cmds.Namespace(),
|
||||
Namespace: Namespace(),
|
||||
},
|
||||
}
|
||||
|
||||
return ctrlClient.Delete(ctx, &cluster)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package kubeconfig
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/k3k/cli/cmds"
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
|
||||
"github.com/rancher/k3k/pkg/controller"
|
||||
"github.com/rancher/k3k/pkg/controller/certs"
|
||||
@@ -16,23 +15,15 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(Scheme)
|
||||
_ = v1alpha1.AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
var (
|
||||
Scheme = runtime.NewScheme()
|
||||
name string
|
||||
cn string
|
||||
org cli.StringSlice
|
||||
@@ -88,11 +79,11 @@ var subcommands = []*cli.Command{
|
||||
Usage: "Generate kubeconfig for clusters",
|
||||
SkipFlagParsing: false,
|
||||
Action: generate,
|
||||
Flags: append(cmds.CommonFlags, generateKubeconfigFlags...),
|
||||
Flags: append(CommonFlags, generateKubeconfigFlags...),
|
||||
},
|
||||
}
|
||||
|
||||
func NewCommand() *cli.Command {
|
||||
func NewKubeconfigCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "kubeconfig",
|
||||
Usage: "Manage kubeconfig for clusters",
|
||||
@@ -102,10 +93,9 @@ func NewCommand() *cli.Command {
|
||||
|
||||
func generate(clx *cli.Context) error {
|
||||
var cluster v1alpha1.Cluster
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", cmds.Kubeconfig)
|
||||
restConfig, err := clientcmd.BuildConfigFromFlags("", Kubeconfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -116,10 +106,9 @@ func generate(clx *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clusterKey := types.NamespacedName{
|
||||
Name: name,
|
||||
Namespace: cmds.Namespace(),
|
||||
Namespace: Namespace(),
|
||||
}
|
||||
|
||||
if err := ctrlClient.Get(ctx, clusterKey, &cluster); err != nil {
|
||||
@@ -130,11 +119,9 @@ func generate(clx *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
host := strings.Split(url.Host, ":")
|
||||
if kubeconfigServerHost != "" {
|
||||
host = []string{kubeconfigServerHost}
|
||||
|
||||
if err := altNames.Set(kubeconfigServerHost); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -157,7 +144,6 @@ func generate(clx *cli.Context) error {
|
||||
logrus.Infof("waiting for cluster to be available..")
|
||||
|
||||
var kubeconfig *clientcmdapi.Config
|
||||
|
||||
if err := retry.OnError(controller.Backoff, apierrors.IsNotFound, func() error {
|
||||
kubeconfig, err = cfg.Extract(ctx, ctrlClient, &cluster, host[0])
|
||||
return err
|
||||
+26
-5
@@ -1,10 +1,15 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
|
||||
"github.com/rancher/k3k/pkg/buildinfo"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -12,9 +17,12 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
debug bool
|
||||
Kubeconfig string
|
||||
namespace string
|
||||
Scheme = runtime.NewScheme()
|
||||
|
||||
debug bool
|
||||
Kubeconfig string
|
||||
namespace string
|
||||
|
||||
CommonFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "kubeconfig",
|
||||
@@ -31,6 +39,11 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
_ = clientgoscheme.AddToScheme(Scheme)
|
||||
_ = v1alpha1.AddToScheme(Scheme)
|
||||
}
|
||||
|
||||
func NewApp() *cli.App {
|
||||
app := cli.NewApp()
|
||||
app.Name = "k3kcli"
|
||||
@@ -48,10 +61,19 @@ func NewApp() *cli.App {
|
||||
if debug {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
app.Version = buildinfo.Version
|
||||
cli.VersionPrinter = func(cCtx *cli.Context) {
|
||||
fmt.Println("k3kcli Version: " + buildinfo.Version)
|
||||
}
|
||||
|
||||
app.Commands = []*cli.Command{
|
||||
NewClusterCommand(),
|
||||
NewKubeconfigCommand(),
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
@@ -59,6 +81,5 @@ func Namespace() string {
|
||||
if namespace == "" {
|
||||
return defaultNamespace
|
||||
}
|
||||
|
||||
return namespace
|
||||
}
|
||||
|
||||
-15
@@ -1,29 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/k3k/cli/cmds"
|
||||
"github.com/rancher/k3k/cli/cmds/cluster"
|
||||
"github.com/rancher/k3k/cli/cmds/kubeconfig"
|
||||
"github.com/rancher/k3k/pkg/buildinfo"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cmds.NewApp()
|
||||
app.Version = buildinfo.Version
|
||||
cli.VersionPrinter = func(cCtx *cli.Context) {
|
||||
fmt.Println("k3kcli Version: " + buildinfo.Version)
|
||||
}
|
||||
|
||||
app.Commands = []*cli.Command{
|
||||
cluster.NewCommand(),
|
||||
kubeconfig.NewCommand(),
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# NAME
|
||||
|
||||
k3kcli - CLI for K3K
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
k3kcli
|
||||
|
||||
```
|
||||
[--debug]
|
||||
```
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
k3kcli [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
```
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
|
||||
**--debug**: Turn on debug logs
|
||||
|
||||
|
||||
# COMMANDS
|
||||
|
||||
## cluster
|
||||
|
||||
cluster command
|
||||
|
||||
### create
|
||||
|
||||
Create new cluster
|
||||
|
||||
>k3kcli cluster create [command options] NAME
|
||||
|
||||
**--agent-args**="": agents extra arguments
|
||||
|
||||
**--agents**="": number of agents (default: 0)
|
||||
|
||||
**--cluster-cidr**="": cluster CIDR
|
||||
|
||||
**--kubeconfig**="": kubeconfig path (default: "/home/jpgouin/.kube/config")
|
||||
|
||||
**--kubeconfig-server**="": override the kubeconfig server host
|
||||
|
||||
**--mode**="": k3k mode type (shared, virtual) (default: "shared")
|
||||
|
||||
**--namespace**="": namespace to create the k3k cluster in
|
||||
|
||||
**--persistence-type**="": persistence mode for the nodes (ephemeral, static, dynamic) (default: "dynamic")
|
||||
|
||||
**--server-args**="": servers extra arguments
|
||||
|
||||
**--servers**="": number of servers (default: 1)
|
||||
|
||||
**--service-cidr**="": service CIDR
|
||||
|
||||
**--storage-class-name**="": storage class name for dynamic persistence type
|
||||
|
||||
**--token**="": token of the cluster
|
||||
|
||||
**--version**="": k3s version
|
||||
|
||||
### delete
|
||||
|
||||
Delete an existing cluster
|
||||
|
||||
>k3kcli cluster delete [command options] NAME
|
||||
|
||||
**--kubeconfig**="": kubeconfig path (default: "/home/jpgouin/.kube/config")
|
||||
|
||||
**--namespace**="": namespace to create the k3k cluster in
|
||||
|
||||
## kubeconfig
|
||||
|
||||
Manage kubeconfig for clusters
|
||||
|
||||
### generate
|
||||
|
||||
Generate kubeconfig for clusters
|
||||
|
||||
**--altNames**="": altNames of the generated certificates for the kubeconfig
|
||||
|
||||
**--cn**="": Common name (CN) of the generated certificates for the kubeconfig (default: "system:admin")
|
||||
|
||||
**--config-name**="": the name of the generated kubeconfig file
|
||||
|
||||
**--expiration-days**="": Expiration date of the certificates used for the kubeconfig (default: 356)
|
||||
|
||||
**--kubeconfig**="": kubeconfig path (default: "/home/jpgouin/.kube/config")
|
||||
|
||||
**--kubeconfig-server**="": override the kubeconfig server host
|
||||
|
||||
**--name**="": cluster name
|
||||
|
||||
**--namespace**="": namespace to create the k3k cluster in
|
||||
|
||||
**--org**="": Organization name (ORG) of the generated certificates for the kubeconfig
|
||||
@@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/rancher/k3k/cli/cmds"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Instantiate the CLI application
|
||||
app := cmds.NewApp()
|
||||
|
||||
// Generate the Markdown documentation
|
||||
md, err := app.ToMarkdown()
|
||||
if err != nil {
|
||||
fmt.Println("Error generating documentation:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outputFile := path.Join(wd, "docs/cli/cli-docs.md")
|
||||
err = os.WriteFile(outputFile, []byte(md), 0644)
|
||||
if err != nil {
|
||||
fmt.Println("Error generating documentation:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Documentation generated at " + outputFile)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
CRD_REF_DOCS_VER := v0.1.0
|
||||
CRD_REF_DOCS := go run github.com/elastic/crd-ref-docs@$(CRD_REF_DOCS_VER)
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
$(CRD_REF_DOCS) --config=config.yaml --renderer=markdown --source-path=../../pkg/apis/k3k.io/v1alpha1 --output-path=crd-docs.md
|
||||
Reference in New Issue
Block a user