Skip to content

Commit

Permalink
Merge pull request openebs-archive#180 from AmitKumarDas/policy-enfor…
Browse files Browse the repository at this point in the history
…ce-new

Introduces volume policy enforcement
  • Loading branch information
prateekpandey14 authored Nov 9, 2017
2 parents ee4c9df + 2a574ba commit 36fd4f1
Show file tree
Hide file tree
Showing 33 changed files with 1,740 additions and 159 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
demo/temp/*
bin/
nohup.out
.DS_Store
.DS_Store
.testfiles/
8 changes: 4 additions & 4 deletions cmd/maya-apiserver/app/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

"github.com/openebs/maya/cmd/maya-apiserver/app/config"
"github.com/openebs/maya/orchprovider"
"github.com/openebs/maya/orchprovider/k8s/v1"
"github.com/openebs/maya/orchprovider/nomad/v1"
k8sv1 "github.com/openebs/maya/orchprovider/k8s/v1"
nomadv1 "github.com/openebs/maya/orchprovider/nomad/v1"
"github.com/openebs/maya/types/v1"
"github.com/openebs/maya/volume/provisioners"
"github.com/openebs/maya/volume/provisioners/jiva"
Expand Down Expand Up @@ -90,7 +90,7 @@ func (ms *MayaApiServer) BootstrapPlugins() error {
// Below is a callback function that creates a new instance of Kubernetes
// orchestration provider
func(label v1.NameLabel, name v1.OrchProviderRegistry) (orchprovider.OrchestratorInterface, error) {
return k8s.NewK8sOrchestrator(label, name)
return k8sv1.NewK8sOrchestrator(label, name)
})
}

Expand All @@ -102,7 +102,7 @@ func (ms *MayaApiServer) BootstrapPlugins() error {
// Below is a callback function that creates a new instance of Nomad
// orchestration provider
func(label v1.NameLabel, name v1.OrchProviderRegistry) (orchprovider.OrchestratorInterface, error) {
return nomad.NewNomadOrchestrator(label, name)
return nomadv1.NewNomadOrchestrator(label, name)
})
}

Expand Down
61 changes: 53 additions & 8 deletions cmd/maya-apiserver/app/server/volume_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/golang/glog"
"github.com/openebs/maya/types/v1"
policies_v1 "github.com/openebs/maya/volume/policies/v1"
"github.com/openebs/maya/volume/provisioners"
)

Expand Down Expand Up @@ -62,8 +63,19 @@ func (s *HTTPServer) volumeList(resp http.ResponseWriter, req *http.Request) (in
// Create a Volume
vol := &v1.Volume{}

// Pass through the policy enforcement logic
policy, err := policies_v1.VolumeGenericPolicy()
if err != nil {
return nil, err
}

vol, err = policy.Enforce(vol)
if err != nil {
return nil, err
}

// Get the persistent volume provisioner instance
pvp, err := provisioners.GetVolumeProvisioner(vol.Labels)
pvp, err := provisioners.GetVolumeProvisioner(nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -106,8 +118,19 @@ func (s *HTTPServer) volumeRead(resp http.ResponseWriter, req *http.Request, vol
vol := &v1.Volume{}
vol.Name = volName

// Pass through the policy enforcement logic
policy, err := policies_v1.VolumeGenericPolicy()
if err != nil {
return nil, err
}

vol, err = policy.Enforce(vol)
if err != nil {
return nil, err
}

// Get persistent volume provisioner instance
pvp, err := provisioners.GetVolumeProvisioner(vol.Labels)
pvp, err := provisioners.GetVolumeProvisioner(nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -152,8 +175,19 @@ func (s *HTTPServer) volumeDelete(resp http.ResponseWriter, req *http.Request, v
vol := &v1.Volume{}
vol.Name = volName

// Pass through the policy enforcement logic
policy, err := policies_v1.VolumeGenericPolicy()
if err != nil {
return nil, err
}

vol, err = policy.Enforce(vol)
if err != nil {
return nil, err
}

// Get the persistent volume provisioner instance
pvp, err := provisioners.GetVolumeProvisioner(vol.Labels)
pvp, err := provisioners.GetVolumeProvisioner(nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -193,10 +227,10 @@ func (s *HTTPServer) volumeAdd(resp http.ResponseWriter, req *http.Request) (int

glog.Infof("Processing Volume add request")

vol := v1.Volume{}
vol := &v1.Volume{}

// The yaml/json spec is decoded to vol struct
if err := decodeBody(req, &vol); err != nil {
if err := decodeBody(req, vol); err != nil {
return nil, CodedError(400, err.Error())
}

Expand All @@ -205,14 +239,25 @@ func (s *HTTPServer) volumeAdd(resp http.ResponseWriter, req *http.Request) (int
return nil, CodedError(400, fmt.Sprintf("Volume name missing in '%v'", vol))
}

// Pass through the policy enforcement logic
policy, err := policies_v1.VolumeAddPolicy()
if err != nil {
return nil, err
}

vol, err = policy.Enforce(vol)
if err != nil {
return nil, err
}

// Get persistent volume provisioner instance
pvp, err := provisioners.GetVolumeProvisioner(vol.Labels)
pvp, err := provisioners.GetVolumeProvisioner(nil)
if err != nil {
return nil, err
}

// Set the volume provisioner profile to provisioner
_, err = pvp.Profile(&vol)
_, err = pvp.Profile(vol)
if err != nil {
return nil, err
}
Expand All @@ -224,7 +269,7 @@ func (s *HTTPServer) volumeAdd(resp http.ResponseWriter, req *http.Request) (int

// TODO
// vol should not be passed again !!
details, err := adder.Add(&vol)
details, err := adder.Add(vol)
if err != nil {
return nil, err
}
Expand Down
7 changes: 3 additions & 4 deletions orchprovider/k8s/v1/doc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Package k8s enables Kubernetes as the orchestration provider
// that aligns to the interfaces suggested by maya api server's orchprovider
// package.
package k8s
// Package k8s enables Kubernetes as the orchestration provider for openebs
// volumes
package v1
111 changes: 88 additions & 23 deletions orchprovider/k8s/v1/k8s.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file registers Kubernetes as an orchestration provider plugin in maya
// api server. This orchestration is for persistent volume provisioners which
// also are registered in maya api server.
package k8s
package v1

import (
"fmt"
Expand All @@ -25,18 +25,30 @@ import (
// 2. orchprovider.NetworkPlacements &
// 3. orchprovider.StoragePlacements
type k8sOrchestrator struct {
// TODO use string datatype
// label specified to this orchestrator
label v1.NameLabel

// TODO use string datatype
// name of the orchestrator as registered in the registry
name v1.OrchProviderRegistry

// volume represents the instance of OpenEBS volume that will
// placed in K8s
volume *v1.Volume

// k8sUtil provides the instance that does the low level
// K8s operations
k8sUtil *k8sUtil

// TODO Deprecate in favour of k8sUtil
// k8sUtlGtr provides the handle to fetch K8sUtilInterface
// NOTE:
// This will be set at runtime.
k8sUtlGtr K8sUtilGetter
}

// Deprecate in favour of NewK8sOrchProvider
// NewK8sOrchestrator provides a new instance of K8sOrchestrator.
func NewK8sOrchestrator(label v1.NameLabel, name v1.OrchProviderRegistry) (orchprovider.OrchestratorInterface, error) {

Expand All @@ -56,24 +68,46 @@ func NewK8sOrchestrator(label v1.NameLabel, name v1.OrchProviderRegistry) (orchp
}, nil
}

// NewK8sOrchProvider provides a new instance of K8sOrchestrator.
func NewK8sOrchProvider() (orchprovider.OrchestratorInterface, error) {
return &k8sOrchestrator{
label: v1.NameLabel("openebs.io/orch-provider"),
name: v1.OrchProviderRegistry("openebs.io/kubernetes"),
}, nil
}

// Label provides the label assigned against this orchestrator.
// This is an implementation of the orchprovider.OrchestratorInterface interface.
func (k *k8sOrchestrator) Label() string {
// TODO
// Do not typecast. Make it typed
// Ensure this for all orch provider implementors
return string(k.label)
}

// Name provides the name of this orchestrator.
// This is an implementation of the orchprovider.OrchestratorInterface interface.
func (k *k8sOrchestrator) Name() string {
// TODO
// Do not typecast. Make it typed
// Ensure this for all orch provider implementors
return string(k.name)
}

// setVolume sets the volume instance
func (k *k8sOrchestrator) setVolume(vol *v1.Volume) error {
if vol == nil {
return fmt.Errorf("Nil volume provided")
}

k.volume = vol
return nil
}

// setK8sUtil sets the k8sUtil instance
func (k *k8sOrchestrator) setK8sUtil(k8sUtil *k8sUtil) error {
if k8sUtil == nil {
return fmt.Errorf("Nil k8s util provided")
}

k.k8sUtil = k8sUtil
return nil
}

// TODO
// Deprecate in favour of orchestrator profile
// Region is not supported by k8sOrchestrator.
Expand Down Expand Up @@ -117,23 +151,54 @@ func k8sOrchUtil(k *k8sOrchestrator, volProfile volProfile.VolumeProvisionerProf
return k.k8sUtlGtr.GetK8sUtil(volProfile)
}

// TODO
// Will it be good if this accepts VolumeProvisionerProfile and updates the
// k8sOrchestrator instance's properties ?
//
// StorageOps provides storage operations instance that deals with all storage
// related functionality by aligning with Kubernetes as the orchestration provider.
//
// NOTE:
// This is an implementation of the orchprovider.OrchestratorInterface interface.
//
// NOTE:
// This is invoked on a per request basis. In other words, every request will
// invoke StorageOps to invoke storage specific operations thereafter.
// StorageOps provides volume operations instance.
func (k *k8sOrchestrator) StorageOps() (orchprovider.StorageOps, bool) {
return k, true
}

// PolicyOps provides a policy operations instance.
// In addition, it is used for various initializations & validations
func (k *k8sOrchestrator) PolicyOps(vol *v1.Volume) (orchprovider.PolicyOps, bool, error) {
err := k.setVolume(vol)
if err != nil {
return nil, true, err
}

err = k.setK8sUtil(&k8sUtil{
volume: vol,
})
if err != nil {
return nil, true, err
}

return k, true, nil
}

// FetchPolicies will fetch volume policies based on the volume
func (k *k8sOrchestrator) FetchPolicies() (map[string]string, error) {
kc, supported, err := k.k8sUtil.K8sClientV2()
if err != nil {
return nil, err
}

if !supported {
return nil, fmt.Errorf("K8s client is not supported")
}

// fetch k8s Deployment operator
scOps, err := kc.StorageClassOps()
if err != nil {
return nil, err
}

sc, err := scOps.Get(k.volume.Labels.K8sStorageClass, metav1.GetOptions{})
if err != nil {
return nil, err
}

return sc.Parameters, nil
}

// AddStorage will add persistent volume running as containers. In OpenEBS
// terms AddStorage will add a VSM.
func (k *k8sOrchestrator) AddStorage(volProProfile volProfile.VolumeProvisionerProfile) (*v1.Volume, error) {
Expand Down Expand Up @@ -821,7 +886,7 @@ func (k *k8sOrchestrator) createReplicaDeployment(volProProfile volProfile.Volum
// Considering above scenarios, it might make more sense to have
// separate K8s Deployment for each replica. However,
// there are dis-advantages in diverging from K8s replica set.
TopologyKey: v1.GetPVPReplicaTopologyKey(vol.Labels),
TopologyKey: v1.GetPVPReplicaTopologyKey(nil),
},
},
},
Expand All @@ -833,7 +898,7 @@ func (k *k8sOrchestrator) createReplicaDeployment(volProProfile volProfile.Volum
Name: vsm + string(v1.ReplicaSuffix) + string(v1.ContainerSuffix),
Image: rImg,
Command: v1.JivaReplicaCmd,
Args: v1.MakeOrDefJivaReplicaArgs(vol.Labels, clusterIP),
Args: v1.MakeOrDefJivaReplicaArgs(vol, clusterIP),
Ports: []k8sApiV1.ContainerPort{
k8sApiV1.ContainerPort{
ContainerPort: v1.DefaultJivaReplicaPort1(),
Expand Down Expand Up @@ -1100,7 +1165,7 @@ func (k *k8sOrchestrator) getReplicaPods(vsm string, podOps k8sCoreV1.PodInterfa
return rp, nil
}

// getPods deletes the Pods w.r.t the VSM
// getPods gets the Pods w.r.t the VSM
func (k *k8sOrchestrator) getPods(vsm string, volProProfile volProfile.VolumeProvisionerProfile) (*k8sApiV1.PodList, error) {

if strings.TrimSpace(vsm) == "" {
Expand Down
Loading

0 comments on commit 36fd4f1

Please sign in to comment.