Skip to content
This repository was archived by the owner on Jul 2, 2020. It is now read-only.

Commit 99eab91

Browse files
committed
Service account authentication for Mkube
Currently, Mkube support only bearer token authentication for secured endpoints, clients that wishes to access resources behind a secured endpoint will need to provide a jwt token using the HTTP `Authorization` header, ie: ``` curl --location --request GET 'http://localhost:8787/api/v1/tenants' --header 'Authorization: Bearer eyJ...' ``` The provided `JWT token` corresponds to the `Kubernetes service account` that Mkube will use to run tasks on behalf of the client ie: list, create, edit, delete tenants, etc. For local development you can use the jwt associated to the `m3-sa` service account, you can get the token running the following command in your terminal: ``` kubectl get secret $(kubectl get serviceaccount m3-sa -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode ``` Then test the token works with `curl` ``` curl --location --request GET 'http://localhost:8787/api/v1/tenants' --header 'Authorization: Bearer eyJ...' ... { "tenants": [ { "creation_date": "2020-06-08 22:35:50 -0700 PDT", "currentState": "Ready", "instance_count": 4, "name": "minio", "volume_count": 16, "volume_size": 1099511627776, "zone_count": 1 } ] } ```
1 parent d7e9626 commit 99eab91

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+213
-4645
lines changed

cluster/cluster.go

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,36 @@
1717
package cluster
1818

1919
import (
20-
v12 "k8s.io/client-go/kubernetes/typed/apps/v1"
21-
20+
operator "github.com/minio/minio-operator/pkg/client/clientset/versioned"
2221
"k8s.io/client-go/kubernetes"
2322
"k8s.io/client-go/rest"
23+
certutil "k8s.io/client-go/util/cert"
2424
)
2525

26-
func GetK8sConfig() *rest.Config {
27-
// creates the in-cluster config
28-
var config *rest.Config
29-
// if k8s service-account token its provided we try to connect using those credentials
30-
if getK8sToken() != "" {
31-
config = &rest.Config{
32-
Host: getK8sAPIServer(),
33-
TLSClientConfig: rest.TLSClientConfig{Insecure: true},
34-
APIPath: "/",
35-
BearerToken: getK8sToken(),
36-
}
37-
} else {
38-
// if no token it's provided use rest.InClusterConfig() to get the service-account
39-
// credentials, assuming we are running inside a k8s pod
40-
var err error
41-
config, err = rest.InClusterConfig()
42-
if err != nil {
43-
panic(err.Error())
44-
}
45-
26+
func GetK8sConfig(token string) *rest.Config {
27+
// if m3 is running inside k8s by default he will have access to the ca cert from the k8s local authority
28+
const (
29+
rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
30+
)
31+
tlsClientConfig := rest.TLSClientConfig{}
32+
if _, err := certutil.NewPool(rootCAFile); err == nil {
33+
tlsClientConfig.CAFile = rootCAFile
34+
}
35+
config := &rest.Config{
36+
Host: getK8sAPIServer(),
37+
TLSClientConfig: tlsClientConfig,
38+
APIPath: "/",
39+
BearerToken: token,
4640
}
47-
4841
return config
4942
}
5043

51-
// K8sClient returns kubernetes client using GetK8sConfig for its config
52-
func K8sClient() (*kubernetes.Clientset, error) {
53-
return kubernetes.NewForConfig(GetK8sConfig())
44+
// OperatorClient returns an operator client using GetK8sConfig for its config
45+
func OperatorClient(token string) (*operator.Clientset, error) {
46+
return operator.NewForConfig(GetK8sConfig(token))
5447
}
5548

56-
// appsV1API encapsulates the appsv1 kubernetes interface to ensure all
57-
// deployment related APIs are of the same version
58-
func appsV1API(client *kubernetes.Clientset) v12.AppsV1Interface {
59-
return client.AppsV1()
49+
// K8sClient returns kubernetes client using GetK8sConfig for its config
50+
func K8sClient(token string) (*kubernetes.Clientset, error) {
51+
return kubernetes.NewForConfig(GetK8sConfig(token))
6052
}

cluster/config.go

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import (
2020
"errors"
2121
"fmt"
2222
"io/ioutil"
23+
"net"
2324
"net/http"
2425
"regexp"
25-
"strconv"
2626
"strings"
2727
"time"
2828

@@ -34,12 +34,12 @@ var (
3434
errCantDetermineMCImage = errors.New("Can't determine MC Image")
3535
)
3636

37-
func getK8sToken() string {
38-
return env.Get(m3K8sToken, "")
39-
}
40-
4137
func getK8sAPIServer() string {
42-
return env.Get(m3K8sAPIServer, "http://localhost:8001")
38+
// if m3 is running inside a k8s pod KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT will contain the k8s api server address
39+
// if m3 is not running inside k8s by default will look for the k8s api server on localhost:8001 (kubectl proxy)
40+
// you can override this using M3_K8S_API_SERVER, ie use http instead of https
41+
host, port := env.Get("KUBERNETES_SERVICE_HOST", "localhost"), env.Get("KUBERNETES_SERVICE_PORT", "8001")
42+
return env.Get(M3K8sAPIServer, "https://"+net.JoinHostPort(host, port))
4343
}
4444

4545
// Returns the namespace in which the controller is installed
@@ -51,58 +51,6 @@ func GetNs() string {
5151
return string(dat)
5252
}
5353

54-
func getKesContainerImage() string {
55-
return env.Get(m3KesImage, "minio/kes:latest")
56-
}
57-
58-
func getKesRunningPort() int {
59-
port, err := strconv.Atoi(env.Get(m3KesPort, "7373"))
60-
if err != nil {
61-
port = 7373
62-
}
63-
return port
64-
}
65-
66-
func getKesMTlsAuth() string {
67-
defaultMode := "verify"
68-
var re = regexp.MustCompile(`^[a-z]+$`)
69-
authMode := env.Get(m3KesMTlsAuth, defaultMode)
70-
if !re.MatchString(authMode) {
71-
authMode = defaultMode
72-
}
73-
return authMode
74-
}
75-
76-
func getKesConfigPath() string {
77-
var re = regexp.MustCompile(`^[a-z_/\-\s0-9\.]+$`)
78-
defaultPath := "kes-config/server-config.toml"
79-
configPath := env.Get(m3KesConfigPath, defaultPath)
80-
if !re.MatchString(configPath) {
81-
configPath = defaultPath
82-
}
83-
return configPath
84-
}
85-
86-
func getKmsAddress() string {
87-
return env.Get(m3KmsAddress, "")
88-
}
89-
90-
func getKmsToken() string {
91-
return env.Get(m3KmsToken, "")
92-
}
93-
94-
func getKmsCACertConfigMap() string {
95-
return env.Get(m3KmsCACertConfigMap, "")
96-
}
97-
98-
func getKmsCACertFileName() string {
99-
return env.Get(m3KmsCACertFileName, "")
100-
}
101-
102-
func getCACertDefaultMounPath() string {
103-
return env.Get(m3CACertDefaultMountPath, "/usr/local/share/ca-certificates")
104-
}
105-
10654
// getLatestMinIOImage returns the latest docker image for MinIO if found on the internet
10755
func getLatestMinIOImage() (*string, error) {
10856
// Create an http client with a 4 second timeout

cluster/const.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,7 @@
1717
package cluster
1818

1919
const (
20-
m3KesImage = "M3_KES_IMAGE"
21-
m3KesPort = "M3_KES_PORT"
22-
m3KesMTlsAuth = "M3_KES_M_TLS_AUTH"
23-
m3KesConfigPath = "M3_KES_CONFIG_FILE_PATH"
24-
m3KmsCACertConfigMap = "M3_KMS_CA_CERT_CONFIG_MAP"
25-
m3KmsCACertFileName = "M3_KMS_CA_CERT_FILE_NAME"
26-
m3CACertDefaultMountPath = "M3_CA_CERT_DEFAULT_MOUNT_PATH"
27-
m3KmsAddress = "M3_KMS_ADDRESS"
28-
m3KmsToken = "M3_KMS_TOKEN"
29-
m3K8sToken = "M3_K8S_TOKEN"
30-
m3K8sAPIServer = "M3_K8S_API_SERVER"
31-
32-
M3MinioImage = "M3_MINIO_IMAGE"
33-
M3MCImage = "M3_MC_IMAGE"
20+
M3K8sAPIServer = "M3_K8S_API_SERVER"
21+
M3MinioImage = "M3_MINIO_IMAGE"
22+
M3MCImage = "M3_MC_IMAGE"
3423
)

0 commit comments

Comments
 (0)