Merge pull request #273 from jp-gouin/readme-1

Update quickstart pre-requisites and generate automatically cli docs
This commit is contained in:
jpgouin
2025-03-03 14:44:11 +01:00
committed by GitHub
13 changed files with 211 additions and 70 deletions

View File

@@ -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

View File

@@ -39,7 +39,10 @@ This section provides instructions on how to install K3k and the `k3kcli`.
### Prerequisites
* [Helm](https://helm.sh) must be installed to use the charts. Please refer to Helm's [documentation](https://helm.sh/docs) to get started.
* An existing [RKE2](https://docs.rke2.io/install/quickstart) Kubernetes cluster (recommended).
* A configured storage provider with a default storage class.
**Note:** If you do not have a storage provider, you can configure the cluster to use ephemeral or static storage. Please consult the [k3kcli advance usage](./docs/advanced-usage.md#using-the-cli) for instructions on using these options.
### Install the K3k controller

View File

@@ -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(),
},
}
}

View File

@@ -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
}
@@ -98,7 +88,8 @@ 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 +97,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{},

View File

@@ -1,4 +1,4 @@
package cluster
package cmds
import (
"errors"

View File

@@ -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,7 +53,7 @@ func delete(clx *cli.Context) error {
cluster := v1alpha1.Cluster{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: cmds.Namespace(),
Namespace: Namespace(),
},
}

View File

@@ -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",
@@ -105,7 +96,7 @@ func generate(clx *cli.Context) error {
ctx := context.Background()
restConfig, err := clientcmd.BuildConfigFromFlags("", cmds.Kubeconfig)
restConfig, err := clientcmd.BuildConfigFromFlags("", Kubeconfig)
if err != nil {
return err
}
@@ -119,7 +110,7 @@ func generate(clx *cli.Context) error {
clusterKey := types.NamespacedName{
Name: name,
Namespace: cmds.Namespace(),
Namespace: Namespace(),
}
if err := ctrlClient.Get(ctx, clusterKey, &cluster); err != nil {

View File

@@ -1,10 +1,14 @@
package cmds
import (
"os"
"fmt"
"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,16 +16,19 @@ const (
)
var (
debug bool
Kubeconfig string
namespace string
Scheme = runtime.NewScheme()
debug bool
Kubeconfig string
namespace string
CommonFlags = []cli.Flag{
&cli.StringFlag{
Name: "kubeconfig",
EnvVars: []string{"KUBECONFIG"},
Usage: "kubeconfig path",
Destination: &Kubeconfig,
Value: os.Getenv("HOME") + "/.kube/config",
Value: "$HOME/.kube/config",
},
&cli.StringFlag{
Name: "namespace",
@@ -31,6 +38,11 @@ var (
}
)
func init() {
_ = clientgoscheme.AddToScheme(Scheme)
_ = v1alpha1.AddToScheme(Scheme)
}
func NewApp() *cli.App {
app := cli.NewApp()
app.Name = "k3kcli"
@@ -52,6 +64,16 @@ func NewApp() *cli.App {
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
}

View File

@@ -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)
}

View File

@@ -6,7 +6,7 @@ This document provides advanced usage information for k3k, including detailed us
The `Cluster` resource provides a variety of fields for customizing the behavior of your virtual clusters. You can check the [CRD documentation](./crds/crd-docs.md) for the full specs.
**Note:** Most of these customization options can also be configured using the `k3kcli` tool. Refer to the `k3kcli` documentation for more details.
**Note:** Most of these customization options can also be configured using the `k3kcli` tool. Refer to the [k3kcli](./cli/cli-docs.md) documentation for more details.
@@ -112,3 +112,21 @@ The `clusterDNS` field specifies the IP address for the CoreDNS service. It need
### `serverArgs`
The `serverArgs` field allows you to specify additional arguments to be passed to the K3s server pods.
## Using the cli
You can check the [k3kcli documentation](./cli/cli-docs.md) for the full specs.
### No storage provider:
* Ephemeral Storage:
```bash
k3kcli cluster create my-cluster --persistence-type ephemeral
```
*Important Notes:*
* Using `--persistence-type ephemeral` will result in data loss if the nodes are restarted.
* It is highly recommended to use `--persistence-type dynamic` with a configured storage class.

98
docs/cli/cli-docs.md Normal file
View File

@@ -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/.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 (dynamic, ephemeral, static) (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/.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/.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

37
docs/cli/genclidoc.go Normal file
View File

@@ -0,0 +1,37 @@
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)
}

View File

@@ -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