なになれ

IT系のことを記録していきます

kubectl pluginを作るのに役立つcli-runtimeの使い方を調べた

kubectl pluginのページで紹介されているcli-runtimeについて、kubeconfig fileを扱うヘルパーとして使えるなどkubectl pliuginを作るのに利用できるとあります。

kubernetes.io

このcli-runtimeを使い方を調べてみたので、その内容を紹介します。

ソースは以下にあります。

github.com

cli-runtimeの使い方

Flagの利用

cli-runtimeでnamespaceのFlagなどを利用する場合、genericclioptionspackageを利用します。
例えば、下記のようにFlagを設定します。

func init() {
    configFlags = genericclioptions.NewConfigFlags(true)
    resourceBuilderFlags = genericclioptions.NewResourceBuilderFlags()
    resourceBuilderFlags.WithAllNamespaces(false)
    configFlags.AddFlags(rootCmd.PersistentFlags())
    resourceBuilderFlags.AddFlags(rootCmd.PersistentFlags())
}

helpを実行すると以下のようにFlagが設定されていることが分かります。

$ go run main.go --help
Usage:
  cli-runtime-example [flags]

Flags:
  -A, --all-namespaces                 If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
      --as string                      Username to impersonate for the operation
      --as-group stringArray           Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
      --cache-dir string               Default HTTP cache directory (default "/Users/odahiroshi/.kube/http-cache")
      --certificate-authority string   Path to a cert file for the certificate authority
      --client-certificate string      Path to a client certificate file for TLS
      --client-key string              Path to a client key file for TLS
      --cluster string                 The name of the kubeconfig cluster to use
      --context string                 The name of the kubeconfig context to use
  -f, --filename strings               identifying the resource.
  -h, --help                           help for cli-runtime-example
      --insecure-skip-tls-verify       If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
      --kubeconfig string              Path to the kubeconfig file to use for CLI requests.
  -n, --namespace string               If present, the namespace scope for this CLI request
  -R, --recursive                      Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory. (default true)
      --request-timeout string         The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
  -s, --server string                  The address and port of the Kubernetes API server
      --tls-server-name string         Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used
      --token string                   Bearer token for authentication to the API server
      --user string                    The name of the kubeconfig user to use

genericclioptionspackageでは、利用可能なFlagをいくつかの単位でまとめて扱っています。
ConfigFlagsResourceBuilderFlagsといった部分です。

どのようなFlagが定義されているかはソースを見るしかなさそうです。
cli-runtime/pkg/genericclioptions at master · kubernetes/cli-runtime · GitHub

API serverへのリクエス

ConfigFlagsのToRESTConfigメソッドを利用すると、API Serverへのリクエストを実行するためのconfigが取得できます。

config, err := configFlags.ToRESTConfig()
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

clientsetを生成する際にconfigを引数として渡すことで、準備ができます。

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

あとは、下記のような感じでKubernetesAPIを実行できます。

clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})

kubeconfigにおける現在のコンテキストの情報を扱う

ConfigFlagsのToRawKubeConfigLoaderメソッドを利用して、ClientConfigを取得します。

rawConfig, err := configFlags.ToRawKubeConfigLoader().RawConfig()
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}

ClientConfigにkubeconfigで設定されている情報が存在するので、下記のように現在のコンテキストの情報を取得できます。
ここでは、現在のnamespaceを取得しています。

namespace := rawConfig.Contexts[rawConfig.CurrentContext].Namespace

まとめ

現在のコンテキストの情報を扱う方法は今まで分からなかったので、cli-runtimeは有用だと思いました。
自分の理解だと、Flagを扱うことやAPI Serverへのリクエスト方法はcli-runtime以外の方法でもできていたのでそこまで必要ではないかもしれません。

参考

GitHub - kubernetes/sample-cli-plugin: Sample kubectl plugin