Fix Session validation for MCS Operator Mode (#191)
* Fix Session validation for MCS Operator Mode * Updated assets
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
func GetK8sConfig(token string) *rest.Config {
|
||||
// if m3 is running inside k8s by default he will have access to the ca cert from the k8s local authority
|
||||
// if console is running inside k8s by default he will have access to the ca cert from the k8s local authority
|
||||
const (
|
||||
rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||
)
|
||||
@@ -33,7 +33,7 @@ func GetK8sConfig(token string) *rest.Config {
|
||||
tlsClientConfig.CAFile = rootCAFile
|
||||
}
|
||||
config := &rest.Config{
|
||||
Host: getK8sAPIServer(),
|
||||
Host: GetK8sAPIServer(),
|
||||
TLSClientConfig: tlsClientConfig,
|
||||
APIPath: "/",
|
||||
BearerToken: token,
|
||||
|
||||
@@ -34,27 +34,27 @@ var (
|
||||
errCantDetermineMCImage = errors.New("can't determine MC Image")
|
||||
)
|
||||
|
||||
func getK8sAPIServer() string {
|
||||
// if m3 is running inside a k8s pod KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT will contain the k8s api server apiServerAddress
|
||||
// if m3 is not running inside k8s by default will look for the k8s api server on localhost:8001 (kubectl proxy)
|
||||
func GetK8sAPIServer() string {
|
||||
// if console is running inside a k8s pod KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT will contain the k8s api server apiServerAddress
|
||||
// if console is not running inside k8s by default will look for the k8s api server on localhost:8001 (kubectl proxy)
|
||||
// NOTE: using kubectl proxy is for local development only, since every request send to localhost:8001 will bypass service account authentication
|
||||
// more info here: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#directly-accessing-the-rest-api
|
||||
// you can override this using M3_K8S_API_SERVER, ie use the k8s cluster from `kubectl config view`
|
||||
// you can override this using MCS_K8S_API_SERVER, ie use the k8s cluster from `kubectl config view`
|
||||
host, port := env.Get("KUBERNETES_SERVICE_HOST", ""), env.Get("KUBERNETES_SERVICE_PORT", "")
|
||||
apiServerAddress := "http://localhost:8001"
|
||||
if host != "" && port != "" {
|
||||
apiServerAddress = "https://" + net.JoinHostPort(host, port)
|
||||
}
|
||||
return env.Get(M3K8sAPIServer, apiServerAddress)
|
||||
return env.Get(McsK8sAPIServer, apiServerAddress)
|
||||
}
|
||||
|
||||
// getK8sAPIServerInsecure allow to tell the k8s client to skip TLS certificate verification, ie: when connecting to a k8s cluster
|
||||
// that uses certificate not trusted by your machine
|
||||
func getK8sAPIServerInsecure() bool {
|
||||
return strings.ToLower(env.Get(m3k8SAPIServerInsecure, "off")) == "on"
|
||||
return strings.ToLower(env.Get(McsK8SAPIServerInsecure, "off")) == "on"
|
||||
}
|
||||
|
||||
// GetNsFromFile assumes mkube is running inside a k8s pod and extract the current namespace from the
|
||||
// GetNsFromFile assumes console is running inside a k8s pod and extract the current namespace from the
|
||||
// /var/run/secrets/kubernetes.io/serviceaccount/namespace file
|
||||
func GetNsFromFile() string {
|
||||
dat, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
|
||||
@@ -64,12 +64,12 @@ func GetNsFromFile() string {
|
||||
return string(dat)
|
||||
}
|
||||
|
||||
// This operation will run only once at mkube startup
|
||||
// This operation will run only once at console startup
|
||||
var namespace = GetNsFromFile()
|
||||
|
||||
// Returns the namespace in which the controller is installed
|
||||
func GetNs() string {
|
||||
return env.Get(M3Namespace, namespace)
|
||||
return env.Get(McsNamespace, namespace)
|
||||
}
|
||||
|
||||
// getLatestMinIOImage returns the latest docker image for MinIO if found on the internet
|
||||
@@ -106,7 +106,7 @@ var latestMinIOImage, errLatestMinIOImage = getLatestMinIOImage(
|
||||
// a preferred image to be used (configured via ENVIRONMENT VARIABLES) GetMinioImage will return that
|
||||
// if not, GetMinioImage will try to obtain the image URL for the latest version of MinIO and return that
|
||||
func GetMinioImage() (*string, error) {
|
||||
image := strings.TrimSpace(env.Get(M3MinioImage, ""))
|
||||
image := strings.TrimSpace(env.Get(McsMinioImage, ""))
|
||||
// if there is a preferred image configured by the user we'll always return that
|
||||
if image != "" {
|
||||
return &image, nil
|
||||
@@ -156,7 +156,7 @@ func getLatestMCImage() (*string, error) {
|
||||
var latestMCImage, errLatestMCImage = getLatestMCImage()
|
||||
|
||||
func GetMCImage() (*string, error) {
|
||||
image := strings.TrimSpace(env.Get(M3MCImage, ""))
|
||||
image := strings.TrimSpace(env.Get(McsMCImage, ""))
|
||||
// if there is a preferred image configured by the user we'll always return that
|
||||
if image != "" {
|
||||
return &image, nil
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package cluster
|
||||
|
||||
const (
|
||||
M3K8sAPIServer = "M3_K8S_API_SERVER"
|
||||
m3k8SAPIServerInsecure = "M3_K8S_API_SERVER_INSECURE"
|
||||
M3MinioImage = "M3_MINIO_IMAGE"
|
||||
M3MCImage = "M3_MC_IMAGE"
|
||||
M3Namespace = "M3_NAMESPACE"
|
||||
McsK8sAPIServer = "MCS_K8S_API_SERVER"
|
||||
McsK8SAPIServerInsecure = "MCS_K8S_API_SERVER_INSECURE"
|
||||
McsMinioImage = "MCS_MINIO_IMAGE"
|
||||
McsMCImage = "MCS_MC_IMAGE"
|
||||
McsNamespace = "MCS_NAMESPACE"
|
||||
)
|
||||
|
||||
27
k8s/console/base/mcs-deployment.yaml
Normal file
27
k8s/console/base/mcs-deployment.yaml
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mcs
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mcs
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mcs
|
||||
spec:
|
||||
serviceAccountName: m3-sa
|
||||
containers:
|
||||
- name: mcs
|
||||
image: minio/mcs:latest
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
args:
|
||||
- /mcs
|
||||
- server
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
name: http
|
||||
- containerPort: 9433
|
||||
name: https
|
||||
11
k8s/operator-console/base/kustomization.yaml
Normal file
11
k8s/operator-console/base/kustomization.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
# beginning of customizations
|
||||
resources:
|
||||
- mcs-service-account.yaml
|
||||
- mcs-cluster-role.yaml
|
||||
- mcs-cluster-role-binding.yaml
|
||||
- mcs-configmap.yaml
|
||||
- mcs-service.yaml
|
||||
- mcs-deployment.yaml
|
||||
- minio-operator.yaml
|
||||
12
k8s/operator-console/base/mcs-cluster-role-binding.yaml
Normal file
12
k8s/operator-console/base/mcs-cluster-role-binding.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: mcs-sa-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: mcs-sa-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: mcs-sa
|
||||
namespace: default
|
||||
77
k8s/operator-console/base/mcs-cluster-role.yaml
Normal file
77
k8s/operator-console/base/mcs-cluster-role.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: mcs-sa-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
- secrets
|
||||
- pods
|
||||
- services
|
||||
- events
|
||||
- resourcequotas
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- "storage.k8s.io"
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets
|
||||
- deployments
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "certificates.k8s.io"
|
||||
resources:
|
||||
- "certificatesigningrequests"
|
||||
- "certificatesigningrequests/approval"
|
||||
- "certificatesigningrequests/status"
|
||||
verbs:
|
||||
- update
|
||||
- create
|
||||
- get
|
||||
- apiGroups:
|
||||
- operator.min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
7
k8s/operator-console/base/mcs-configmap.yaml
Normal file
7
k8s/operator-console/base/mcs-configmap.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mcs-env
|
||||
data:
|
||||
MCS_PORT: "9090"
|
||||
MCS_TLS_PORT: "9443"
|
||||
@@ -18,7 +18,7 @@ spec:
|
||||
image: minio/mcs:latest
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
env:
|
||||
- name: MCS_MKUBE_ADMIN_ONLY
|
||||
- name: MCS_OPERATOR_MODE
|
||||
value: "on"
|
||||
args:
|
||||
- /mcs
|
||||
5
k8s/operator-console/base/mcs-service-account.yaml
Normal file
5
k8s/operator-console/base/mcs-service-account.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: mcs-sa
|
||||
namespace: default
|
||||
14
k8s/operator-console/base/mcs-service.yaml
Normal file
14
k8s/operator-console/base/mcs-service.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mcs
|
||||
labels:
|
||||
name: mcs
|
||||
spec:
|
||||
ports:
|
||||
- port: 9090
|
||||
name: http
|
||||
- port: 9443
|
||||
name: https
|
||||
selector:
|
||||
app: mcs
|
||||
203
k8s/operator-console/base/minio-operator.yaml
Normal file
203
k8s/operator-console/base/minio-operator.yaml
Normal file
@@ -0,0 +1,203 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: minioinstances.operator.min.io
|
||||
spec:
|
||||
group: operator.min.io
|
||||
scope: Namespaced
|
||||
names:
|
||||
kind: MinIOInstance
|
||||
singular: minioinstance
|
||||
plural: minioinstances
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
schema:
|
||||
# openAPIV3Schema is the schema for validating custom objects.
|
||||
# Refer https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#specifying-a-structural-schema
|
||||
# for more details
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
replicas:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 32
|
||||
image:
|
||||
type: string
|
||||
serviceName:
|
||||
type: string
|
||||
volumesPerServer:
|
||||
type: integer
|
||||
mountPath:
|
||||
type: string
|
||||
podManagementPolicy:
|
||||
type: string
|
||||
enum: [Parallel, OrderedReady]
|
||||
default: Parallel
|
||||
requestAutoCert:
|
||||
type: boolean
|
||||
default: false
|
||||
version:
|
||||
type: string
|
||||
mountpath:
|
||||
type: string
|
||||
subpath:
|
||||
type: string
|
||||
mcs:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
image:
|
||||
type: string
|
||||
replicas:
|
||||
type: integer
|
||||
default: 2
|
||||
mcsSecret:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
kes:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
properties:
|
||||
image:
|
||||
type: string
|
||||
replicas:
|
||||
type: integer
|
||||
default: 2
|
||||
kesSecret:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
currentState:
|
||||
type: string
|
||||
subresources:
|
||||
# status enables the status subresource.
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: Current State
|
||||
type: string
|
||||
jsonPath: ".status.currentState"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: minio-operator-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- namespaces
|
||||
- secrets
|
||||
- pods
|
||||
- services
|
||||
- events
|
||||
verbs:
|
||||
- get
|
||||
- watch
|
||||
- create
|
||||
- list
|
||||
- delete
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets
|
||||
- deployments
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "certificates.k8s.io"
|
||||
resources:
|
||||
- "certificatesigningrequests"
|
||||
- "certificatesigningrequests/approval"
|
||||
- "certificatesigningrequests/status"
|
||||
verbs:
|
||||
- update
|
||||
- create
|
||||
- get
|
||||
- delete
|
||||
- apiGroups:
|
||||
- operator.min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- min.io
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- "*"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: minio-operator
|
||||
namespace: default
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: minio-operator-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: minio-operator-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: minio-operator
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: minio-operator
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
name: minio-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: minio-operator
|
||||
spec:
|
||||
serviceAccountName: minio-operator
|
||||
containers:
|
||||
- name: minio-operator
|
||||
image: minio/k8s-operator:2.0.8
|
||||
imagePullPolicy: IfNotPresent
|
||||
# To specify cluster domain, un comment the following:
|
||||
# env:
|
||||
# - name: CLUSTER_DOMAIN
|
||||
# value: mycluster.mydomain
|
||||
@@ -29,18 +29,18 @@ import (
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// LoginMkubeRequest login mkube request
|
||||
// LoginOperatorRequest login operator request
|
||||
//
|
||||
// swagger:model loginMkubeRequest
|
||||
type LoginMkubeRequest struct {
|
||||
// swagger:model loginOperatorRequest
|
||||
type LoginOperatorRequest struct {
|
||||
|
||||
// jwt
|
||||
// Required: true
|
||||
Jwt *string `json:"jwt"`
|
||||
}
|
||||
|
||||
// Validate validates this login mkube request
|
||||
func (m *LoginMkubeRequest) Validate(formats strfmt.Registry) error {
|
||||
// Validate validates this login operator request
|
||||
func (m *LoginOperatorRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateJwt(formats); err != nil {
|
||||
@@ -53,7 +53,7 @@ func (m *LoginMkubeRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LoginMkubeRequest) validateJwt(formats strfmt.Registry) error {
|
||||
func (m *LoginOperatorRequest) validateJwt(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("jwt", "body", m.Jwt); err != nil {
|
||||
return err
|
||||
@@ -63,7 +63,7 @@ func (m *LoginMkubeRequest) validateJwt(formats strfmt.Registry) error {
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *LoginMkubeRequest) MarshalBinary() ([]byte, error) {
|
||||
func (m *LoginOperatorRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -71,8 +71,8 @@ func (m *LoginMkubeRequest) MarshalBinary() ([]byte, error) {
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *LoginMkubeRequest) UnmarshalBinary(b []byte) error {
|
||||
var res LoginMkubeRequest
|
||||
func (m *LoginOperatorRequest) UnmarshalBinary(b []byte) error {
|
||||
var res LoginOperatorRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -22,8 +22,7 @@ import (
|
||||
"github.com/minio/minio/pkg/env"
|
||||
)
|
||||
|
||||
// GetOperatorOnly gets MCS mkube admin mode status set on env variable
|
||||
// or default one
|
||||
func GetOperatorOnly() bool {
|
||||
return strings.ToLower(env.Get(McsmKubeAdminOnly, "off")) == "on"
|
||||
// GetOperatorMode gets MCS Operator mode status set on env variable or default one
|
||||
func GetOperatorMode() bool {
|
||||
return strings.ToLower(env.Get(mcsOperatorMode, "off")) == "on"
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@
|
||||
package acl
|
||||
|
||||
const (
|
||||
McsmKubeAdminOnly = "MCS_MKUBE_ADMIN_ONLY"
|
||||
mcsOperatorMode = "MCS_OPERATOR_MODE"
|
||||
)
|
||||
|
||||
@@ -233,7 +233,7 @@ var operatorRules = map[string]ConfigurationActionSet{
|
||||
}
|
||||
|
||||
// operatorOnly ENV variable
|
||||
var operatorOnly = GetOperatorOnly()
|
||||
var operatorOnly = GetOperatorMode()
|
||||
|
||||
// GetActionsStringFromPolicy extract the admin/s3 actions from a given policy and return them in []string format
|
||||
//
|
||||
|
||||
@@ -21,17 +21,17 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/minio/mcs/pkg/auth/mkube"
|
||||
"github.com/minio/mcs/cluster"
|
||||
"github.com/minio/minio-go/v6/pkg/credentials"
|
||||
)
|
||||
|
||||
// mkubeCredentialsProvider is an struct to hold the JWT (service account token)
|
||||
type mkubeCredentialsProvider struct {
|
||||
// operatorCredentialsProvider is an struct to hold the JWT (service account token)
|
||||
type operatorCredentialsProvider struct {
|
||||
serviceAccountJWT string
|
||||
}
|
||||
|
||||
// Implementing the interfaces of the minio Provider, we use this to leverage on the existing mcs Authentication flow
|
||||
func (s mkubeCredentialsProvider) Retrieve() (credentials.Value, error) {
|
||||
func (s operatorCredentialsProvider) Retrieve() (credentials.Value, error) {
|
||||
return credentials.Value{
|
||||
AccessKeyID: "",
|
||||
SecretAccessKey: "",
|
||||
@@ -40,38 +40,32 @@ func (s mkubeCredentialsProvider) Retrieve() (credentials.Value, error) {
|
||||
}
|
||||
|
||||
// IsExpired dummy function, must be implemented in order to work with the minio provider authentication
|
||||
func (s mkubeCredentialsProvider) IsExpired() bool {
|
||||
func (s operatorCredentialsProvider) IsExpired() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// isServiceAccountTokenValid will make an authenticated request (using bearer token) against Mkube hostname, if the
|
||||
// request success means the provided jwt its a valid service account token and the MCS user can use it for future requests
|
||||
// until it fails
|
||||
// isServiceAccountTokenValid will make an authenticated request (using bearer token) against kubernetes api, if the
|
||||
// request success means the provided jwt its a valid service account token and the MCS user can use it for future
|
||||
// requests until it fails
|
||||
func isServiceAccountTokenValid(client *http.Client, jwt string) bool {
|
||||
url := fmt.Sprintf("%s/api/v1/tenants", mkube.GetMkubeEndpoint())
|
||||
m3Req, err := http.NewRequest("GET", url, nil)
|
||||
//# Explore the API with TOKEN
|
||||
//curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
|
||||
apiURL := fmt.Sprintf("%s/api", cluster.GetK8sAPIServer())
|
||||
req, _ := http.NewRequest("GET", apiURL, nil)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt))
|
||||
_, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return false
|
||||
}
|
||||
token := fmt.Sprintf("Bearer %s", jwt)
|
||||
m3Req.Header.Add("Authorization", token)
|
||||
resp, err := client.Do(m3Req)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return false
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
// GetMcsCredentialsFromMkube will validate the provided JWT (service account token) and return it in the form of credentials.Credentials
|
||||
func GetMcsCredentialsFromMkube(jwt string) (*credentials.Credentials, error) {
|
||||
if isServiceAccountTokenValid(mkube.HTTPClient, jwt) {
|
||||
return credentials.New(mkubeCredentialsProvider{serviceAccountJWT: jwt}), nil
|
||||
// GetMcsCredentialsForOperator will validate the provided JWT (service account token) and return it in the form of credentials.Credentials
|
||||
func GetMcsCredentialsForOperator(jwt string) (*credentials.Credentials, error) {
|
||||
client := http.Client{}
|
||||
if isServiceAccountTokenValid(&client, jwt) {
|
||||
return credentials.New(operatorCredentialsProvider{serviceAccountJWT: jwt}), nil
|
||||
}
|
||||
return nil, errInvalidCredentials
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package mkube
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/minio/pkg/env"
|
||||
)
|
||||
|
||||
var (
|
||||
certDontExists = "File certificate doesn't exists: %s"
|
||||
)
|
||||
|
||||
// getMkubeEndpoint returns the hostname of mkube
|
||||
func GetMkubeEndpoint() string {
|
||||
return env.Get(McsMkubeHost, "http://m3:8787")
|
||||
}
|
||||
|
||||
// getMkubeEndpointIsSecure returns true or false depending on the protocol in Mkube URL
|
||||
func getMkubeEndpointIsSecure() bool {
|
||||
server := GetMkubeEndpoint()
|
||||
if strings.Contains(server, "://") {
|
||||
parts := strings.Split(server, "://")
|
||||
if len(parts) > 1 {
|
||||
if parts[0] == "https" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// If MCS_M3_SERVER_TLS_CA_CERTIFICATE is true mcs will load a list of certificates into the
|
||||
// http.client rootCAs store, this is useful for testing or when working with self-signed certificates
|
||||
func getMkubeServerTLSRootCAs() []string {
|
||||
caCertFileNames := strings.TrimSpace(env.Get(McsMkubeTLSCACertificate, ""))
|
||||
if caCertFileNames == "" {
|
||||
return []string{}
|
||||
}
|
||||
return strings.Split(caCertFileNames, ",")
|
||||
}
|
||||
|
||||
// FileExists verifies if a file exist on the desired location and its not a folder
|
||||
func FileExists(filename string) bool {
|
||||
info, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// GetMkubeHTTPClient returns an http.Client with custom configurations used by MCS to talk to Mkube
|
||||
// custom configurations include the use of CA certificates
|
||||
func getMkubeHTTPClient() *http.Client {
|
||||
httpTransport := &http.Transport{}
|
||||
// If Mkube server is running with TLS enabled and it's using a self-signed certificate
|
||||
// or a certificate issued by a custom certificate authority we prepare a new custom *http.Transport
|
||||
if getMkubeEndpointIsSecure() {
|
||||
caCertFileNames := getMkubeServerTLSRootCAs()
|
||||
tlsConfig := &tls.Config{
|
||||
// Can't use SSLv3 because of POODLE and BEAST
|
||||
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
|
||||
// Can't use TLSv1.1 because of RC4 cipher usage
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
// If CAs certificates are configured we save them to the http.Client RootCAs store
|
||||
if len(caCertFileNames) > 0 {
|
||||
certs := x509.NewCertPool()
|
||||
for _, caCert := range caCertFileNames {
|
||||
// Validate certificate exists
|
||||
if FileExists(caCert) {
|
||||
pemData, err := ioutil.ReadFile(caCert)
|
||||
if err != nil {
|
||||
// if there was an error reading pem file stop mcs
|
||||
panic(err)
|
||||
}
|
||||
certs.AppendCertsFromPEM(pemData)
|
||||
} else {
|
||||
// if provided cert filename doesn't exists stop mcs
|
||||
panic(fmt.Sprintf(certDontExists, caCert))
|
||||
}
|
||||
}
|
||||
tlsConfig.RootCAs = certs
|
||||
}
|
||||
httpTransport.TLSClientConfig = tlsConfig
|
||||
}
|
||||
|
||||
// Return http client with default configuration
|
||||
return &http.Client{
|
||||
Transport: httpTransport,
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPClient it's a public variable that contains the HTTP configuration to be used by MCS to talk to Mkube
|
||||
// This function will run only once
|
||||
var HTTPClient = getMkubeHTTPClient()
|
||||
@@ -1,22 +0,0 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package mkube
|
||||
|
||||
const (
|
||||
McsMkubeHost = "MCS_M3_HOSTNAME"
|
||||
McsMkubeTLSCACertificate = "MCS_M3_SERVER_TLS_CA_CERTIFICATE"
|
||||
)
|
||||
File diff suppressed because one or more lines are too long
@@ -122,7 +122,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => {
|
||||
|
||||
const loginStrategyEndpoints: LoginStrategyRoutes = {
|
||||
form: "/api/v1/login",
|
||||
"service-account": "/api/v1/login/mkube",
|
||||
"service-account": "/api/v1/login/operator",
|
||||
};
|
||||
const loginStrategyPayload: LoginStrategyPayload = {
|
||||
form: { accessKey, secretKey },
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/minio/mcs/pkg/auth"
|
||||
xjwt "github.com/minio/mcs/pkg/auth/jwt"
|
||||
"github.com/minio/mcs/pkg/auth/ldap"
|
||||
"github.com/minio/mcs/pkg/auth/mkube"
|
||||
"github.com/minio/minio-go/v6"
|
||||
"github.com/minio/minio-go/v6/pkg/credentials"
|
||||
)
|
||||
@@ -162,18 +161,14 @@ func (s mcsSTSAssumeRole) IsExpired() bool {
|
||||
// STSClient contains http.client configuration need it by STSAssumeRole
|
||||
var STSClient = PrepareSTSClient()
|
||||
var MinioEndpoint = getMinIOServer()
|
||||
var MkubeEndpoint = mkube.GetMkubeEndpoint()
|
||||
|
||||
func newMcsCredentials(accessKey, secretKey, location string) (*credentials.Credentials, error) {
|
||||
// Future authentication methods can be added under this switch statement
|
||||
switch {
|
||||
// MKUBE authentication for MCS
|
||||
case acl.GetOperatorOnly():
|
||||
// authentication for Operator Console
|
||||
case acl.GetOperatorMode():
|
||||
{
|
||||
if MkubeEndpoint == "" {
|
||||
return nil, errors.New("endpoint cannot be empty for Mkube")
|
||||
}
|
||||
creds, err := auth.GetMcsCredentialsFromMkube(secretKey)
|
||||
creds, err := auth.GetMcsCredentialsForOperator(secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -236,5 +236,5 @@ func getSecureExpectCTHeader() string {
|
||||
// getTenantMemorySize Memory size value to be used when generating the
|
||||
// MinioInstance request
|
||||
func getTenantMemorySize() string {
|
||||
return env.Get(M3TenantMemorySize, defaultTenantMemorySize)
|
||||
return env.Get(McsTenantMemorySize, defaultTenantMemorySize)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/minio/mcs/pkg/acl"
|
||||
|
||||
"github.com/minio/mcs/models"
|
||||
"github.com/minio/mcs/pkg"
|
||||
"github.com/minio/mcs/pkg/auth"
|
||||
@@ -60,9 +62,18 @@ func configureAPI(api *operations.McsAPI) http.Handler {
|
||||
// Applies when the "x-token" header is set
|
||||
|
||||
api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) {
|
||||
if auth.IsJWTValid(token) {
|
||||
prin := models.Principal(token)
|
||||
return &prin, nil
|
||||
if acl.GetOperatorMode() {
|
||||
// here we just check the token is present on the request, authentication will be done
|
||||
// by kubernetes api server
|
||||
if token != "" {
|
||||
prin := models.Principal(token)
|
||||
return &prin, nil
|
||||
}
|
||||
} else {
|
||||
if auth.IsJWTValid(token) {
|
||||
prin := models.Principal(token)
|
||||
return &prin, nil
|
||||
}
|
||||
}
|
||||
log.Printf("Access attempt with incorrect api key auth: %s", token)
|
||||
return nil, errors.New(401, "incorrect api key auth")
|
||||
@@ -99,7 +110,7 @@ func configureAPI(api *operations.McsAPI) http.Handler {
|
||||
// Register admin Service Account Handlers
|
||||
registerServiceAccountsHandlers(api)
|
||||
|
||||
//m3
|
||||
// Operator Console
|
||||
// Register tenant handlers
|
||||
registerTenantHandlers(api)
|
||||
// Register ResourceQuota handlers
|
||||
|
||||
@@ -17,12 +17,6 @@
|
||||
package restapi
|
||||
|
||||
const (
|
||||
// consts for common configuration
|
||||
M3Version = `0.1.0`
|
||||
M3Hostname = "M3_HOSTNAME"
|
||||
M3Port = "M3_PORT"
|
||||
M3TLSHostname = "M3_TLS_HOSTNAME"
|
||||
M3TLSPort = "M3_TLS_PORT"
|
||||
// M3TenantMemorySize Memory size to be used when creating MinioInstance request
|
||||
M3TenantMemorySize = "M3_TENANT_MEMORY_SIZE"
|
||||
// McsTenantMemorySize Memory size to be used when creating MinioInstance request
|
||||
McsTenantMemorySize = "MCS_TENANT_MEMORY_SIZE"
|
||||
)
|
||||
|
||||
@@ -754,21 +754,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/login/mkube": {
|
||||
"/login/oauth2/auth": {
|
||||
"post": {
|
||||
"security": [],
|
||||
"tags": [
|
||||
"UserAPI"
|
||||
],
|
||||
"summary": "Login to Mkube.",
|
||||
"operationId": "LoginMkube",
|
||||
"summary": "Identity Provider oauth2 callback endpoint.",
|
||||
"operationId": "LoginOauth2Auth",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/loginMkubeRequest"
|
||||
"$ref": "#/definitions/loginOauth2AuthRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -788,21 +788,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/login/oauth2/auth": {
|
||||
"/login/operator": {
|
||||
"post": {
|
||||
"security": [],
|
||||
"tags": [
|
||||
"UserAPI"
|
||||
],
|
||||
"summary": "Identity Provider oauth2 callback endpoint.",
|
||||
"operationId": "LoginOauth2Auth",
|
||||
"summary": "Login to Operator Console.",
|
||||
"operationId": "LoginOperator",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/loginOauth2AuthRequest"
|
||||
"$ref": "#/definitions/loginOperatorRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -2126,17 +2126,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginMkubeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"jwt"
|
||||
],
|
||||
"properties": {
|
||||
"jwt": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginOauth2AuthRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -2152,6 +2141,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginOperatorRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"jwt"
|
||||
],
|
||||
"properties": {
|
||||
"jwt": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -3396,21 +3396,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/login/mkube": {
|
||||
"/login/oauth2/auth": {
|
||||
"post": {
|
||||
"security": [],
|
||||
"tags": [
|
||||
"UserAPI"
|
||||
],
|
||||
"summary": "Login to Mkube.",
|
||||
"operationId": "LoginMkube",
|
||||
"summary": "Identity Provider oauth2 callback endpoint.",
|
||||
"operationId": "LoginOauth2Auth",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/loginMkubeRequest"
|
||||
"$ref": "#/definitions/loginOauth2AuthRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -3430,21 +3430,21 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/login/oauth2/auth": {
|
||||
"/login/operator": {
|
||||
"post": {
|
||||
"security": [],
|
||||
"tags": [
|
||||
"UserAPI"
|
||||
],
|
||||
"summary": "Identity Provider oauth2 callback endpoint.",
|
||||
"operationId": "LoginOauth2Auth",
|
||||
"summary": "Login to Operator Console.",
|
||||
"operationId": "LoginOperator",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/loginOauth2AuthRequest"
|
||||
"$ref": "#/definitions/loginOperatorRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -4782,17 +4782,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginMkubeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"jwt"
|
||||
],
|
||||
"properties": {
|
||||
"jwt": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginOauth2AuthRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -4808,6 +4797,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginOperatorRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"jwt"
|
||||
],
|
||||
"properties": {
|
||||
"jwt": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -170,15 +170,15 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
|
||||
return err
|
||||
}
|
||||
// udpate ingress with this new service
|
||||
m3Ingress, err := clientset.ExtensionsV1beta1().Ingresses(namespace).Get(context.Background(), "mkube-ingress", metav1.GetOptions{})
|
||||
consoleIngress, err := clientset.ExtensionsV1beta1().Ingresses(namespace).Get(context.Background(), "console-ingress", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certsInIngress := m3Ingress.ObjectMeta.Annotations["networking.gke.io/managed-certificates"]
|
||||
certsInIngress := consoleIngress.ObjectMeta.Annotations["networking.gke.io/managed-certificates"]
|
||||
allCerts := strings.Split(certsInIngress, ",")
|
||||
allCerts = append(allCerts, manCertName)
|
||||
m3Ingress.ObjectMeta.Annotations["networking.gke.io/managed-certificates"] = strings.Join(allCerts, ",")
|
||||
consoleIngress.ObjectMeta.Annotations["networking.gke.io/managed-certificates"] = strings.Join(allCerts, ",")
|
||||
|
||||
tenantNodePortIoS := intstr.IntOrString{
|
||||
Type: intstr.Int,
|
||||
@@ -190,7 +190,7 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
|
||||
IntVal: int32(tenantMcsNodePort),
|
||||
}
|
||||
|
||||
m3Ingress.Spec.Rules = append(m3Ingress.Spec.Rules, extensionsBeta1.IngressRule{
|
||||
consoleIngress.Spec.Rules = append(consoleIngress.Spec.Rules, extensionsBeta1.IngressRule{
|
||||
Host: tenantDomain,
|
||||
IngressRuleValue: extensionsBeta1.IngressRuleValue{
|
||||
HTTP: &extensionsBeta1.HTTPIngressRuleValue{
|
||||
@@ -205,7 +205,7 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
|
||||
},
|
||||
},
|
||||
})
|
||||
m3Ingress.Spec.Rules = append(m3Ingress.Spec.Rules, extensionsBeta1.IngressRule{
|
||||
consoleIngress.Spec.Rules = append(consoleIngress.Spec.Rules, extensionsBeta1.IngressRule{
|
||||
Host: tenantMcsDomain,
|
||||
IngressRuleValue: extensionsBeta1.IngressRuleValue{
|
||||
HTTP: &extensionsBeta1.HTTPIngressRuleValue{
|
||||
@@ -221,7 +221,7 @@ func gkeIntegration(clientset *kubernetes.Clientset, tenantName string, namespac
|
||||
},
|
||||
})
|
||||
|
||||
_, err = clientset.ExtensionsV1beta1().Ingresses(namespace).Update(context.Background(), m3Ingress, metav1.UpdateOptions{})
|
||||
_, err = clientset.ExtensionsV1beta1().Ingresses(namespace).Update(context.Background(), consoleIngress, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -156,12 +156,12 @@ func NewMcsAPI(spec *loads.Document) *McsAPI {
|
||||
UserAPILoginDetailHandler: user_api.LoginDetailHandlerFunc(func(params user_api.LoginDetailParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.LoginDetail has not yet been implemented")
|
||||
}),
|
||||
UserAPILoginMkubeHandler: user_api.LoginMkubeHandlerFunc(func(params user_api.LoginMkubeParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.LoginMkube has not yet been implemented")
|
||||
}),
|
||||
UserAPILoginOauth2AuthHandler: user_api.LoginOauth2AuthHandlerFunc(func(params user_api.LoginOauth2AuthParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.LoginOauth2Auth has not yet been implemented")
|
||||
}),
|
||||
UserAPILoginOperatorHandler: user_api.LoginOperatorHandlerFunc(func(params user_api.LoginOperatorParams) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.LoginOperator has not yet been implemented")
|
||||
}),
|
||||
UserAPILogoutHandler: user_api.LogoutHandlerFunc(func(params user_api.LogoutParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.Logout has not yet been implemented")
|
||||
}),
|
||||
@@ -327,10 +327,10 @@ type McsAPI struct {
|
||||
UserAPILoginHandler user_api.LoginHandler
|
||||
// UserAPILoginDetailHandler sets the operation handler for the login detail operation
|
||||
UserAPILoginDetailHandler user_api.LoginDetailHandler
|
||||
// UserAPILoginMkubeHandler sets the operation handler for the login mkube operation
|
||||
UserAPILoginMkubeHandler user_api.LoginMkubeHandler
|
||||
// UserAPILoginOauth2AuthHandler sets the operation handler for the login oauth2 auth operation
|
||||
UserAPILoginOauth2AuthHandler user_api.LoginOauth2AuthHandler
|
||||
// UserAPILoginOperatorHandler sets the operation handler for the login operator operation
|
||||
UserAPILoginOperatorHandler user_api.LoginOperatorHandler
|
||||
// UserAPILogoutHandler sets the operation handler for the logout operation
|
||||
UserAPILogoutHandler user_api.LogoutHandler
|
||||
// UserAPIMakeBucketHandler sets the operation handler for the make bucket operation
|
||||
@@ -533,12 +533,12 @@ func (o *McsAPI) Validate() error {
|
||||
if o.UserAPILoginDetailHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.LoginDetailHandler")
|
||||
}
|
||||
if o.UserAPILoginMkubeHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.LoginMkubeHandler")
|
||||
}
|
||||
if o.UserAPILoginOauth2AuthHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.LoginOauth2AuthHandler")
|
||||
}
|
||||
if o.UserAPILoginOperatorHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.LoginOperatorHandler")
|
||||
}
|
||||
if o.UserAPILogoutHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.LogoutHandler")
|
||||
}
|
||||
@@ -820,11 +820,11 @@ func (o *McsAPI) initHandlerCache() {
|
||||
if o.handlers["POST"] == nil {
|
||||
o.handlers["POST"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["POST"]["/login/mkube"] = user_api.NewLoginMkube(o.context, o.UserAPILoginMkubeHandler)
|
||||
o.handlers["POST"]["/login/oauth2/auth"] = user_api.NewLoginOauth2Auth(o.context, o.UserAPILoginOauth2AuthHandler)
|
||||
if o.handlers["POST"] == nil {
|
||||
o.handlers["POST"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["POST"]["/login/oauth2/auth"] = user_api.NewLoginOauth2Auth(o.context, o.UserAPILoginOauth2AuthHandler)
|
||||
o.handlers["POST"]["/login/operator"] = user_api.NewLoginOperator(o.context, o.UserAPILoginOperatorHandler)
|
||||
if o.handlers["POST"] == nil {
|
||||
o.handlers["POST"] = make(map[string]http.Handler)
|
||||
}
|
||||
|
||||
@@ -28,40 +28,40 @@ import (
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
)
|
||||
|
||||
// LoginMkubeHandlerFunc turns a function with the right signature into a login mkube handler
|
||||
type LoginMkubeHandlerFunc func(LoginMkubeParams) middleware.Responder
|
||||
// LoginOperatorHandlerFunc turns a function with the right signature into a login operator handler
|
||||
type LoginOperatorHandlerFunc func(LoginOperatorParams) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn LoginMkubeHandlerFunc) Handle(params LoginMkubeParams) middleware.Responder {
|
||||
func (fn LoginOperatorHandlerFunc) Handle(params LoginOperatorParams) middleware.Responder {
|
||||
return fn(params)
|
||||
}
|
||||
|
||||
// LoginMkubeHandler interface for that can handle valid login mkube params
|
||||
type LoginMkubeHandler interface {
|
||||
Handle(LoginMkubeParams) middleware.Responder
|
||||
// LoginOperatorHandler interface for that can handle valid login operator params
|
||||
type LoginOperatorHandler interface {
|
||||
Handle(LoginOperatorParams) middleware.Responder
|
||||
}
|
||||
|
||||
// NewLoginMkube creates a new http.Handler for the login mkube operation
|
||||
func NewLoginMkube(ctx *middleware.Context, handler LoginMkubeHandler) *LoginMkube {
|
||||
return &LoginMkube{Context: ctx, Handler: handler}
|
||||
// NewLoginOperator creates a new http.Handler for the login operator operation
|
||||
func NewLoginOperator(ctx *middleware.Context, handler LoginOperatorHandler) *LoginOperator {
|
||||
return &LoginOperator{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*LoginMkube swagger:route POST /login/mkube UserAPI loginMkube
|
||||
/*LoginOperator swagger:route POST /login/operator UserAPI loginOperator
|
||||
|
||||
Login to Mkube.
|
||||
Login to Operator Console.
|
||||
|
||||
*/
|
||||
type LoginMkube struct {
|
||||
type LoginOperator struct {
|
||||
Context *middleware.Context
|
||||
Handler LoginMkubeHandler
|
||||
Handler LoginOperatorHandler
|
||||
}
|
||||
|
||||
func (o *LoginMkube) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
func (o *LoginOperator) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
var Params = NewLoginMkubeParams()
|
||||
var Params = NewLoginOperatorParams()
|
||||
|
||||
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
@@ -33,18 +33,18 @@ import (
|
||||
"github.com/minio/mcs/models"
|
||||
)
|
||||
|
||||
// NewLoginMkubeParams creates a new LoginMkubeParams object
|
||||
// NewLoginOperatorParams creates a new LoginOperatorParams object
|
||||
// no default values defined in spec.
|
||||
func NewLoginMkubeParams() LoginMkubeParams {
|
||||
func NewLoginOperatorParams() LoginOperatorParams {
|
||||
|
||||
return LoginMkubeParams{}
|
||||
return LoginOperatorParams{}
|
||||
}
|
||||
|
||||
// LoginMkubeParams contains all the bound params for the login mkube operation
|
||||
// LoginOperatorParams contains all the bound params for the login operator operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters LoginMkube
|
||||
type LoginMkubeParams struct {
|
||||
// swagger:parameters LoginOperator
|
||||
type LoginOperatorParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
@@ -53,21 +53,21 @@ type LoginMkubeParams struct {
|
||||
Required: true
|
||||
In: body
|
||||
*/
|
||||
Body *models.LoginMkubeRequest
|
||||
Body *models.LoginOperatorRequest
|
||||
}
|
||||
|
||||
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||
// for simple values it will use straight method calls.
|
||||
//
|
||||
// To ensure default values, the struct must have been initialized with NewLoginMkubeParams() beforehand.
|
||||
func (o *LoginMkubeParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
// To ensure default values, the struct must have been initialized with NewLoginOperatorParams() beforehand.
|
||||
func (o *LoginOperatorParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
if runtime.HasBody(r) {
|
||||
defer r.Body.Close()
|
||||
var body models.LoginMkubeRequest
|
||||
var body models.LoginOperatorRequest
|
||||
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||
if err == io.EOF {
|
||||
res = append(res, errors.Required("body", "body", ""))
|
||||
@@ -30,14 +30,14 @@ import (
|
||||
"github.com/minio/mcs/models"
|
||||
)
|
||||
|
||||
// LoginMkubeCreatedCode is the HTTP code returned for type LoginMkubeCreated
|
||||
const LoginMkubeCreatedCode int = 201
|
||||
// LoginOperatorCreatedCode is the HTTP code returned for type LoginOperatorCreated
|
||||
const LoginOperatorCreatedCode int = 201
|
||||
|
||||
/*LoginMkubeCreated A successful login.
|
||||
/*LoginOperatorCreated A successful login.
|
||||
|
||||
swagger:response loginMkubeCreated
|
||||
swagger:response loginOperatorCreated
|
||||
*/
|
||||
type LoginMkubeCreated struct {
|
||||
type LoginOperatorCreated struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
@@ -45,25 +45,25 @@ type LoginMkubeCreated struct {
|
||||
Payload *models.LoginResponse `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewLoginMkubeCreated creates LoginMkubeCreated with default headers values
|
||||
func NewLoginMkubeCreated() *LoginMkubeCreated {
|
||||
// NewLoginOperatorCreated creates LoginOperatorCreated with default headers values
|
||||
func NewLoginOperatorCreated() *LoginOperatorCreated {
|
||||
|
||||
return &LoginMkubeCreated{}
|
||||
return &LoginOperatorCreated{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the login mkube created response
|
||||
func (o *LoginMkubeCreated) WithPayload(payload *models.LoginResponse) *LoginMkubeCreated {
|
||||
// WithPayload adds the payload to the login operator created response
|
||||
func (o *LoginOperatorCreated) WithPayload(payload *models.LoginResponse) *LoginOperatorCreated {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the login mkube created response
|
||||
func (o *LoginMkubeCreated) SetPayload(payload *models.LoginResponse) {
|
||||
// SetPayload sets the payload to the login operator created response
|
||||
func (o *LoginOperatorCreated) SetPayload(payload *models.LoginResponse) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *LoginMkubeCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
func (o *LoginOperatorCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(201)
|
||||
if o.Payload != nil {
|
||||
@@ -74,11 +74,11 @@ func (o *LoginMkubeCreated) WriteResponse(rw http.ResponseWriter, producer runti
|
||||
}
|
||||
}
|
||||
|
||||
/*LoginMkubeDefault Generic error response.
|
||||
/*LoginOperatorDefault Generic error response.
|
||||
|
||||
swagger:response loginMkubeDefault
|
||||
swagger:response loginOperatorDefault
|
||||
*/
|
||||
type LoginMkubeDefault struct {
|
||||
type LoginOperatorDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
@@ -87,41 +87,41 @@ type LoginMkubeDefault struct {
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewLoginMkubeDefault creates LoginMkubeDefault with default headers values
|
||||
func NewLoginMkubeDefault(code int) *LoginMkubeDefault {
|
||||
// NewLoginOperatorDefault creates LoginOperatorDefault with default headers values
|
||||
func NewLoginOperatorDefault(code int) *LoginOperatorDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &LoginMkubeDefault{
|
||||
return &LoginOperatorDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the login mkube default response
|
||||
func (o *LoginMkubeDefault) WithStatusCode(code int) *LoginMkubeDefault {
|
||||
// WithStatusCode adds the status to the login operator default response
|
||||
func (o *LoginOperatorDefault) WithStatusCode(code int) *LoginOperatorDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the login mkube default response
|
||||
func (o *LoginMkubeDefault) SetStatusCode(code int) {
|
||||
// SetStatusCode sets the status to the login operator default response
|
||||
func (o *LoginOperatorDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the login mkube default response
|
||||
func (o *LoginMkubeDefault) WithPayload(payload *models.Error) *LoginMkubeDefault {
|
||||
// WithPayload adds the payload to the login operator default response
|
||||
func (o *LoginOperatorDefault) WithPayload(payload *models.Error) *LoginOperatorDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the login mkube default response
|
||||
func (o *LoginMkubeDefault) SetPayload(payload *models.Error) {
|
||||
// SetPayload sets the payload to the login operator default response
|
||||
func (o *LoginOperatorDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *LoginMkubeDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
func (o *LoginOperatorDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(o._statusCode)
|
||||
if o.Payload != nil {
|
||||
@@ -28,15 +28,15 @@ import (
|
||||
golangswaggerpaths "path"
|
||||
)
|
||||
|
||||
// LoginMkubeURL generates an URL for the login mkube operation
|
||||
type LoginMkubeURL struct {
|
||||
// LoginOperatorURL generates an URL for the login operator operation
|
||||
type LoginOperatorURL struct {
|
||||
_basePath string
|
||||
}
|
||||
|
||||
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *LoginMkubeURL) WithBasePath(bp string) *LoginMkubeURL {
|
||||
func (o *LoginOperatorURL) WithBasePath(bp string) *LoginOperatorURL {
|
||||
o.SetBasePath(bp)
|
||||
return o
|
||||
}
|
||||
@@ -44,15 +44,15 @@ func (o *LoginMkubeURL) WithBasePath(bp string) *LoginMkubeURL {
|
||||
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *LoginMkubeURL) SetBasePath(bp string) {
|
||||
func (o *LoginOperatorURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *LoginMkubeURL) Build() (*url.URL, error) {
|
||||
func (o *LoginOperatorURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/login/mkube"
|
||||
var _path = "/login/operator"
|
||||
|
||||
_basePath := o._basePath
|
||||
if _basePath == "" {
|
||||
@@ -64,7 +64,7 @@ func (o *LoginMkubeURL) Build() (*url.URL, error) {
|
||||
}
|
||||
|
||||
// Must is a helper function to panic when the url builder returns an error
|
||||
func (o *LoginMkubeURL) Must(u *url.URL, err error) *url.URL {
|
||||
func (o *LoginOperatorURL) Must(u *url.URL, err error) *url.URL {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -75,17 +75,17 @@ func (o *LoginMkubeURL) Must(u *url.URL, err error) *url.URL {
|
||||
}
|
||||
|
||||
// String returns the string representation of the path with query string
|
||||
func (o *LoginMkubeURL) String() string {
|
||||
func (o *LoginOperatorURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *LoginMkubeURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
func (o *LoginOperatorURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on LoginMkubeURL")
|
||||
return nil, errors.New("scheme is required for a full url on LoginOperatorURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on LoginMkubeURL")
|
||||
return nil, errors.New("host is required for a full url on LoginOperatorURL")
|
||||
}
|
||||
|
||||
base, err := o.Build()
|
||||
@@ -99,6 +99,6 @@ func (o *LoginMkubeURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
}
|
||||
|
||||
// StringFull returns the string representation of a complete url
|
||||
func (o *LoginMkubeURL) StringFull(scheme, host string) string {
|
||||
func (o *LoginOperatorURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -61,12 +61,12 @@ func registerLoginHandlers(api *operations.McsAPI) {
|
||||
}
|
||||
return user_api.NewLoginOauth2AuthCreated().WithPayload(loginResponse)
|
||||
})
|
||||
api.UserAPILoginMkubeHandler = user_api.LoginMkubeHandlerFunc(func(params user_api.LoginMkubeParams) middleware.Responder {
|
||||
loginResponse, err := getLoginMkubeResponse(params.Body)
|
||||
api.UserAPILoginOperatorHandler = user_api.LoginOperatorHandlerFunc(func(params user_api.LoginOperatorParams) middleware.Responder {
|
||||
loginResponse, err := getLoginOperatorResponse(params.Body)
|
||||
if err != nil {
|
||||
return user_api.NewLoginMkubeDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
|
||||
return user_api.NewLoginOperatorDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
|
||||
}
|
||||
return user_api.NewLoginMkubeCreated().WithPayload(loginResponse)
|
||||
return user_api.NewLoginOperatorCreated().WithPayload(loginResponse)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func getLoginDetailsResponse() (*models.LoginDetails, error) {
|
||||
ctx := context.Background()
|
||||
loginStrategy := models.LoginDetailsLoginStrategyForm
|
||||
redirectURL := ""
|
||||
if acl.GetOperatorOnly() {
|
||||
if acl.GetOperatorMode() {
|
||||
loginStrategy = models.LoginDetailsLoginStrategyServiceAccount
|
||||
} else if oauth2.IsIdpEnabled() {
|
||||
loginStrategy = models.LoginDetailsLoginStrategyRedirect
|
||||
@@ -261,8 +261,8 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
|
||||
return nil, errorGeneric
|
||||
}
|
||||
|
||||
// getLoginMkubeResponse validate the provided service account token against mkube
|
||||
func getLoginMkubeResponse(lmr *models.LoginMkubeRequest) (*models.LoginResponse, error) {
|
||||
// getLoginOperatorResponse validate the provided service account token against k8s api
|
||||
func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginResponse, error) {
|
||||
creds, err := newMcsCredentials("", *lmr.Jwt, "")
|
||||
if err != nil {
|
||||
log.Println("error login:", err)
|
||||
|
||||
10
swagger.yml
10
swagger.yml
@@ -60,16 +60,16 @@ paths:
|
||||
security: []
|
||||
tags:
|
||||
- UserAPI
|
||||
/login/mkube:
|
||||
/login/operator:
|
||||
post:
|
||||
summary: Login to Mkube.
|
||||
operationId: LoginMkube
|
||||
summary: Login to Operator Console.
|
||||
operationId: LoginOperator
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/loginMkubeRequest'
|
||||
$ref: '#/definitions/loginOperatorRequest'
|
||||
responses:
|
||||
201:
|
||||
description: A successful login.
|
||||
@@ -1462,7 +1462,7 @@ definitions:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
loginMkubeRequest:
|
||||
loginOperatorRequest:
|
||||
type: object
|
||||
required:
|
||||
- jwt
|
||||
|
||||
Reference in New Issue
Block a user