Skip to content

Commit

Permalink
Add support for mcs (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
Praveenrajmani authored May 5, 2020
1 parent 8fdab5f commit 0f74d0a
Show file tree
Hide file tree
Showing 12 changed files with 744 additions and 10 deletions.
6 changes: 6 additions & 0 deletions docs/operator-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ If the MirrorInstance is named as `mirrorinstance`, resources and their names as
| spec.nodeSelector | Add a selector which must be true for the MinIOInstance pod to fit on a node. Refer [this document](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) for details.|
| spec.tolerations | Define a toleration for the MinIOInstance pod to match on a taint. Refer [this document](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) for details. |
| spec.securityContext | Define a security context for the MinIOInstance pod. Refer [this document](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for details. |
| spec.mcs | Defines the mcs configuration. mcs is a graphical user interface for MinIO. Refer [this](https://github.com/minio/mcs) |
| spec.mcs.image | Defines the mcs image (If unspecified, It will be set to the default: `minio/mcs:v0.0.2`) |
| spec.mcs.mcsAccessKey | Specify the access key to be used by mcs |
| spec.mcs.mcsSecret | Use this secret to assign mcs credentials to MinIOInstance. |
| spec.mcs.selector | Add a selector for the mcs. Which will be used by the mcs container for grouping. (Note: Should not match the labels provided in `spec.selector`) |
| spec.mcs.metadata | This allows a way to map metadata to the mcs container. Internally `metadata` is a struct type as [explained here](https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta). [Note: Should match the labels in `spec.mcs.selector`] |

## MirrorInstance Fields

Expand Down
24 changes: 24 additions & 0 deletions examples/minioinstance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ type: Opaque
data:
accesskey: bWluaW8= # base 64 encoded "minio" (echo -n 'minio' | base64)
secretkey: bWluaW8xMjM= # based 64 encoded "minio123" (echo -n 'minio123' | base64)
## Secrets defined for mcs
---
apiVersion: v1
kind: Secret
metadata:
name: minio-mcs-secret
type: Opaque
data:
mcshmacjwt: WU9VUkpXVFNJR05JTkdTRUNSRVQ= # base 64 encoded "YOURJWTSIGNINGSECRET" (echo -n 'YOURJWTSIGNINGSECRET' | base64)
mcspbkdfpassphrase: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
mcspbkdfsalt: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
mcssecretkey: WU9VUk1DU1NFQ1JFVA== # base 64 encoded "YOURMCSSECRET" (echo -n 'YOURMCSSECRET' | base64)
---
apiVersion: v1
kind: Service
Expand Down Expand Up @@ -95,6 +107,18 @@ spec:
# key: dedicated
# operator: Equal
# value: storage
## Define configuration for mcs (A graphical user interface for MinIO)
mcs:
image: minio/mcs:v0.0.2
mcsAccessKey: "mcs"
mcsSecret:
name: minio-mcs-secret
selector:
matchLabels:
app: mcs # Should match spec.mcs.metadata.labels
metadata:
labels:
app: mcs # Should match spec.mcs.selector.matchLabels
## Add environment variables to be set in MinIO container (https://github.com/minio/minio/tree/master/docs/config)
env:
- name: MINIO_BROWSER
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ go 1.13
require (
github.com/evanphx/json-patch v4.5.0+incompatible // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/groupcache v0.0.0-20180924190550-6f2cf27854a4 // indirect
github.com/golang/protobuf v1.3.3 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/minio/minio v0.0.0-20200501124117-09571d03a531
github.com/stretchr/testify v1.4.0
k8s.io/api v0.18.0
k8s.io/apimachinery v0.18.0
Expand Down
326 changes: 324 additions & 2 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func main() {

mainController := cluster.NewController(kubeClient, controllerClient, *certClient,
kubeInformerFactory.Apps().V1().StatefulSets(),
kubeInformerFactory.Apps().V1().Deployments(),
minioInformerFactory.Miniooperator().V1beta1().MinIOInstances(),
kubeInformerFactory.Core().V1().Services())

Expand Down
117 changes: 116 additions & 1 deletion pkg/apis/miniooperator.min.io/v1beta1/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@
package v1beta1

import (
"context"
"errors"
"fmt"
"net"
"path"
"strconv"

"github.com/golang/glog"

constants "github.com/minio/minio-operator/pkg/constants"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

constants "github.com/minio/minio-operator/pkg/constants"
"github.com/minio/minio/pkg/bucket/policy"
"github.com/minio/minio/pkg/bucket/policy/condition"
iampolicy "github.com/minio/minio/pkg/iam/policy"
"github.com/minio/minio/pkg/madmin"
)

// HasCredsSecret returns true if the user has provided a secret
Expand Down Expand Up @@ -150,6 +159,10 @@ func (mi *MinIOInstance) EnsureDefaults() *MinIOInstance {
}
}

if mi.HasMcsEnabled() && mi.Spec.Mcs.Image == "" {
mi.Spec.Mcs.Image = constants.DefaultMcsImage
}

return mi
}

Expand All @@ -168,6 +181,18 @@ func (mi *MinIOInstance) GetHosts() []string {
return hosts
}

// GetServiceHost returns headless service Host.
// current MinIOInstance
func (mi *MinIOInstance) GetServiceHost() string {
if mi.Spec.Zones[0].Servers == 1 {
msg := "Please set the server count > 1"
glog.V(2).Infof(msg)
return ""
}
hostStr := fmt.Sprintf("%s.%s.svc."+constants.ClusterDomain, mi.GetHeadlessServiceName(), mi.Namespace)
return net.JoinHostPort(hostStr, strconv.Itoa(constants.MinIOServicePortNumber))
}

// GetWildCardName returns the wild card name managed by headless service created for
// current MinIOInstance
func (mi *MinIOInstance) GetWildCardName() string {
Expand Down Expand Up @@ -211,3 +236,93 @@ func (mi *MirrorInstance) HasMetadata() bool {
func (mi *MirrorInstance) HasSelector() bool {
return mi.Spec.Selector != nil
}

// HasMcsEnabled checks if the mcs has been enabled by the user
func (mi *MinIOInstance) HasMcsEnabled() bool {
return mi.Spec.Mcs != nil
}

// HasMcsSecret returns true if the user has provided an mcs secret
// for a MinIOInstance else false
func (mi *MinIOInstance) HasMcsSecret() bool {
return mi.Spec.Mcs != nil && mi.Spec.Mcs.McsSecret != nil
}

// HasMcsMetadata returns true if the user has provided a mcs metadata
// for a MinIOInstance else false
func (mi *MinIOInstance) HasMcsMetadata() bool {
return mi.Spec.Mcs != nil && mi.Spec.Mcs.Metadata != nil
}

// HasMcsSelector returns true if the user has provided a mcs selector
// for a MinIOInstance else false
func (mi *MinIOInstance) HasMcsSelector() bool {
return mi.Spec.Mcs != nil && mi.Spec.Mcs.Selector != nil
}

// CreateMcsUser function creates an admin user
func (mi *MinIOInstance) CreateMcsUser(minioSecret, mcsSecret map[string][]byte) error {

var accessKey, secretKey, mcsSecretKey []byte
var ok bool

host := mi.GetServiceHost()
if host == "" {
return errors.New("MCS MINIO SERVER is empty")
}

accessKey, ok = minioSecret["accesskey"]
if !ok {
return errors.New("accesskey not provided")
}

secretKey, ok = minioSecret["secretkey"]
if !ok {
return errors.New("secretkey not provided")
}

mcsSecretKey, ok = mcsSecret["mcssecretkey"]
if !ok {
return errors.New("mcssecretkey not provided")
}

madmClnt, err := madmin.New(host, string(accessKey), string(secretKey), false)
if err != nil {
return err
}

if err = madmClnt.AddUser(context.Background(), string(mi.Spec.Mcs.McsAccessKey), string(mcsSecretKey)); err != nil {
return err
}

// Create policy
p := iampolicy.Policy{
Version: iampolicy.DefaultVersion,
Statements: []iampolicy.Statement{
{
SID: policy.ID(""),
Effect: policy.Allow,
Actions: iampolicy.NewActionSet(iampolicy.AllAdminActions),
Resources: iampolicy.NewResourceSet(),
Conditions: condition.NewFunctions(),
},
{
SID: policy.ID(""),
Effect: policy.Allow,
Actions: iampolicy.NewActionSet(iampolicy.AllActions),
Resources: iampolicy.NewResourceSet(iampolicy.NewResource("*", "")),
Conditions: condition.NewFunctions(),
},
},
}

if err = madmClnt.AddCannedPolicy(context.Background(), constants.MCSAdminPolicyName, &p); err != nil {
return err
}

if err = madmClnt.SetPolicy(context.Background(), constants.MCSAdminPolicyName, string(mi.Spec.Mcs.McsAccessKey), false); err != nil {
return err
}

return nil
}
12 changes: 12 additions & 0 deletions pkg/apis/miniooperator.min.io/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ type MinIOInstanceSpec struct {
// Definition for Cluster in given MinIO cluster
// +optional
Zones []Zone `json:"zones"`
// McsConfig is for setting up minio/mcs for graphical user interface
//+optional
Mcs *McsConfig `json:"mcs,omitempty"`
}

// MinIOInstanceStatus is the status for a MinIOInstance resource
Expand Down Expand Up @@ -207,3 +210,12 @@ type Args struct {
Target string `json:"target"`
Flags []string `json:"flags"`
}

// McsConfig defines the credentials for mcs
type McsConfig struct {
Image string `json:"image,omitempty"`
McsAccessKey string `json:"mcsAccessKey"`
McsSecret *corev1.LocalObjectReference `json:"mcsSecret,omitempty"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
Metadata *metav1.ObjectMeta `json:"metadata,omitempty"`
}
15 changes: 15 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ const MinIOPort = 9000
// MinIOServicePortName specifies the default Service's port name, e.g. for automatic protocol selection in Istio
const MinIOServicePortName = "http-minio"

// MinIOServicePortNumber specifies the default Service's port number.
const MinIOServicePortNumber = 9000

// McsPort specifies the default Mcs port number.
const McsPort = 9090

// MinIOVolumeName specifies the default volume name for MinIO volumes
const MinIOVolumeName = "export"

Expand All @@ -54,6 +60,9 @@ const DefaultMinIOImage = "minio/minio:RELEASE.2020-05-01T22-19-14Z"
// DefaultMCImage specifies the default mc Docker hub image
const DefaultMCImage = "minio/mc:RELEASE.2020-04-25T00-43-23Z"

// DefaultMcsImage specifies the latest Mcs Docker hub image
const DefaultMcsImage = "minio/mcs:v0.0.2"

// MinIOServerName specifies the default container name for MinIOInstance
const MinIOServerName = "minio"

Expand Down Expand Up @@ -121,6 +130,12 @@ const DefaultVolumesPerServer = 1
// DefaultZoneName specifies the default zone name
const DefaultZoneName = "zone-0"

// McsName specifies the default container name for Mcs
const McsName = "mcs"

// MCSAdminPolicyName denotes the policy name for MCS user
const MCSAdminPolicyName = "mcsAdmin"

func getEnv(key, defaultValue string) string {
value := os.Getenv(key)
if len(value) == 0 {
Expand Down
Loading

0 comments on commit 0f74d0a

Please sign in to comment.