Skip to content

Commit

Permalink
Merge pull request #436 from binoychitale/add-user-certs
Browse files Browse the repository at this point in the history
Add user certs
  • Loading branch information
trawler authored Nov 26, 2020
2 parents 09e8052 + 77500a6 commit c18051f
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 2 deletions.
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func init() {
rootCmd.AddCommand(APICmd)
rootCmd.AddCommand(etcdCmd)
rootCmd.AddCommand(docs)
rootCmd.AddCommand(userCmd)

longDesc = "k0s - The zero friction Kubernetes - https://k0sproject.io"
if build.EulaNotice != "" {
Expand Down
135 changes: 135 additions & 0 deletions cmd/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package cmd

import (
"bytes"
"encoding/base64"

"github.com/cloudflare/cfssl/log"
"github.com/k0sproject/k0s/pkg/certificate"
"github.com/k0sproject/k0s/pkg/constant"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"

"html/template"
"io/ioutil"
"os"
"path"
)

func init() {
userCreateCmd.Flags().StringVar(&groups, "groups", "", "Specify groups")
userCmd.AddCommand(userCreateCmd)
}

var (
groups string

userKubeconfigTemplate = template.Must(template.New("kubeconfig").Parse(`
apiVersion: v1
clusters:
- cluster:
server: {{.JoinURL}}
certificate-authority-data: {{.CACert}}
name: k0s
contexts:
- context:
cluster: k0s
user: {{.User}}
name: k0s
current-context: k0s
kind: Config
preferences: {}
users:
- name: {{.User}}
user:
client-certificate-data: {{.ClientCert}}
client-key-data: {{.ClientKey}}
`))

// userCmd creates new certs and kubeConfig for a user
userCmd = &cobra.Command{
Use: "user",
Short: "Manage user access",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}

userCreateCmd = &cobra.Command{
Use: "create [username]",
Short: "Create a kubeconfig for a user",
Long: `Create a kubeconfig with a signed certificate and public key for a given user (and optionally user groups)
Note: A certificate once signed cannot be revoked for a particular user`,
Example: ` Command to create a kubeconfig for a user:
CLI argument:
$ k0s user create [username]
optionally add groups:
$ k0s user create [username] --groups [groups]`,
RunE: func(cmd *cobra.Command, args []string) error {
// Disable logrus and cfssl logging for user commands to avoid printing debug info to stdout
logrus.SetLevel(logrus.FatalLevel)
log.Level = log.LevelFatal

if len(args) == 0 {
return errors.New("Username is mandatory")
}
var username = args[0]
clusterConfig, err := ConfigFromYaml(cfgFile)
if err != nil {
return err
}
var config = constant.GetConfig(dataDir)

caCert, err := ioutil.ReadFile(path.Join(config.CertRootDir, "ca.crt"))
if err != nil {
return errors.Wrapf(err, "failed to read cluster ca certificate, is the control plane initialized on this node?")
}

caCertPath, caCertKey := path.Join(config.CertRootDir, "ca.crt"), path.Join(config.CertRootDir, "ca.key")

if err != nil {
return err
}

userReq := certificate.Request{
Name: username,
CN: username,
O: groups,
CACert: caCertPath,
CAKey: caCertKey,
}
certManager := certificate.Manager{
K0sVars: config,
}
userCert, err := certManager.EnsureCertificate(userReq, "root")
if err != nil {
return err
}

data := struct {
CACert string
ClientCert string
ClientKey string
User string
JoinURL string
}{
CACert: base64.StdEncoding.EncodeToString(caCert),
ClientCert: base64.StdEncoding.EncodeToString([]byte(userCert.Cert)),
ClientKey: base64.StdEncoding.EncodeToString([]byte(userCert.Key)),
User: username,
JoinURL: clusterConfig.Spec.API.APIAddress(),
}

var buf bytes.Buffer

err = userKubeconfigTemplate.Execute(&buf, &data)
if err != nil {
return err
}
os.Stdout.Write(buf.Bytes())
return nil
},
}
)
5 changes: 3 additions & 2 deletions docs/cli/k0s.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ building a Kubernetes clusters a matter of just copying an executable to every h
--data-dir string Data Directory for k0s (default: /var/lib/k0s). DO NOT CHANGE for an existing setup, things will break!
-d, --debug Debug logging (default: false)
-h, --help help for k0s
-l, --logging stringToString Logging Levels for the different components (default [etcd=info,containerd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1,kube-scheduler=1,kubelet=1])
-l, --logging stringToString Logging Levels for the different components (default [kube-scheduler=1,kubelet=1,etcd=info,containerd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1])
```

### SEE ALSO
Expand All @@ -26,7 +26,8 @@ building a Kubernetes clusters a matter of just copying an executable to every h
* [k0s etcd](k0s_etcd.md) - Manage etcd cluster
* [k0s server](k0s_server.md) - Run server
* [k0s token](k0s_token.md) - Manage join tokens
* [k0s user](k0s_user.md) - Manage user access
* [k0s version](k0s_version.md) - Print the k0s version
* [k0s worker](k0s_worker.md) - Run worker

###### Auto generated by spf13/cobra on 20-Nov-2020
###### Auto generated by spf13/cobra on 24-Nov-2020
29 changes: 29 additions & 0 deletions docs/cli/k0s_user.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## k0s user

Manage user access

```
k0s user [flags]
```

### Options

```
-h, --help help for user
```

### Options inherited from parent commands

```
-c, --config string config file (default: ./k0s.yaml)
--data-dir string Data Directory for k0s (default: /var/lib/k0s). DO NOT CHANGE for an existing setup, things will break!
-d, --debug Debug logging (default: false)
-l, --logging stringToString Logging Levels for the different components (default [kube-scheduler=1,kubelet=1,etcd=info,containerd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1])
```

### SEE ALSO

* [k0s](k0s.md) - k0s - Zero Friction Kubernetes
* [k0s user create](k0s_user_create.md) - Create a kubeconfig for a user

###### Auto generated by spf13/cobra on 24-Nov-2020
45 changes: 45 additions & 0 deletions docs/cli/k0s_user_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## k0s user create

Create a kubeconfig for a user

### Synopsis

Create a kubeconfig with a signed certificate and public key for a given user (and optionally user groups)
Note: A certificate once signed cannot be revoked for a particular user

```
k0s user create [username] [flags]
```

### Examples

```
Command to create a kubeconfig for a user:
CLI argument:
$ k0s user create [username]
optionally add groups:
$ k0s user create [username] --groups [groups]
```

### Options

```
--groups string Specify groups
-h, --help help for create
```

### Options inherited from parent commands

```
-c, --config string config file (default: ./k0s.yaml)
--data-dir string Data Directory for k0s (default: /var/lib/k0s). DO NOT CHANGE for an existing setup, things will break!
-d, --debug Debug logging (default: false)
-l, --logging stringToString Logging Levels for the different components (default [kube-scheduler=1,kubelet=1,etcd=info,containerd=info,konnectivity-server=1,kube-apiserver=1,kube-controller-manager=1])
```

### SEE ALSO

* [k0s user](k0s_user.md) - Manage user access

###### Auto generated by spf13/cobra on 24-Nov-2020
21 changes: 21 additions & 0 deletions docs/create-cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,24 @@ The on the new controller, run:
```sh
k0s server "long-join-token"
```

## Adding a Cluster User

To add a user to cluster, use the [user create](cli/k0s_user_create.md) command.
This will output a kubeconfig for the user, which can be used for authentication.

On the controller, run the following to generate a kubeconfig for a user :
```shell script
k0s user create [username]
```
### Enabling Access to Cluster Resources
To allow the user access to the cluster, the user needs to be created with the `system:masters` group:

```shell script
clusterUser="testUser"
k0s user create --groups "system:masters" $clusterUser > ~/clusterUser.kubeconfig
```
Create the proper roleBinding, to allow the user access to the resources:
```shell script
kubectl create clusterrolebinding $clusterUser-admin-binding --clusterrole=admin --user=$clusterUser
```

0 comments on commit c18051f

Please sign in to comment.