Fix Session validation for MCS Operator Mode (#191)

* Fix Session validation for MCS Operator Mode

* Updated assets
This commit is contained in:
Daniel Valdivia
2020-07-08 13:55:08 -07:00
committed by GitHub
parent 8a74b795c8
commit 328133d3ff
41 changed files with 608 additions and 398 deletions

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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:
- "*"

View File

@@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mcs-env
data:
MCS_PORT: "9090"
MCS_TLS_PORT: "9443"

View File

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

View File

@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: mcs-sa
namespace: default

View 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

View 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

View File

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

View File

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

View File

@@ -17,5 +17,5 @@
package acl
const (
McsmKubeAdminOnly = "MCS_MKUBE_ADMIN_ONLY"
mcsOperatorMode = "MCS_OPERATOR_MODE"
)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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": [

View File

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

View File

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

View File

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

View File

@@ -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", ""))

View File

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

View File

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

View File

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

View File

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