Skip to content

Commit

Permalink
feat(nfs-server): provision nfs server resource in user provided name…
Browse files Browse the repository at this point in the history
…space (#58)

* support to deploy nfs-server in custom namespace

  nfs-provisioner deployment can be configured with env NFSServerNamespace
  with namespace value to create nfs-server deployment in a provided namespace.

  Note: This requires nfs-provisioner should have permission to create/delete deployment,
  service, PVC resource in the provided namespace.

* adding test case to verify nfs-server creation in custom namespace
* updating deployment yaml with env OPENEBS_IO_NFS_SERVER_NS
* updating helm chart to set OPENEBS_IO_NFS_SERVER_NS env value
* updating helm/kind-action version to v1.2.0

Signed-off-by: mayank <[email protected]>
  • Loading branch information
mynktl authored Jul 8, 2021
1 parent ea1579d commit e0a9e18
Show file tree
Hide file tree
Showing 15 changed files with 382 additions and 154 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/chart-lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run: ct lint --config ct.yml

- name: Create kind cluster
uses: helm/kind-action@v1.0.0
uses: helm/kind-action@v1.2.0
if: steps.list-changed.outputs.changed == 'true'

- name: Run chart-testing (install)
Expand Down
2 changes: 1 addition & 1 deletion deploy/helm/charts/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Helm chart for OpenEBS Dynamic NFS PV. For instructions to install
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.4.0
version: 0.4.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 0.4.0
Expand Down
1 change: 1 addition & 0 deletions deploy/helm/charts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ helm install openebs-nfs openebs-nfs/nfs-provisioner --namespace openebs --creat
| `nfsProvisioner.resources` | Resource request and limit for the container | `true` |
| `nfsProvisioner.securityContext` | Security context for container | `""` |
| `nfsProvisioner.tolerations` | NFS Provisioner pod toleration values | `""` |
| `nfsProvisioner.nfsServerNamespace` | NFS server namespace | `"openebs"` |
| `nfsStorageClass.backendStorageClass` | StorageClass to be used to provision the backend volume. If not specified, the default StorageClass is used. | `""` |
| `nfsStorageClass.isDefaultClass` | Make 'openebs-kernel-nfs' the default StorageClass | `"false"` |
| `nfsStorageClass.reclaimPolicy` | ReclaimPolicy for NFS PVs | `"Delete"` |
Expand Down
5 changes: 5 additions & 0 deletions deploy/helm/charts/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ spec:
# leader election is enabled.
- name: LEADER_ELECTION_ENABLED
value: "{{ .Values.nfsProvisioner.enableLeaderElection }}"
{{- if .Values.nfsProvisioner.nfsServerNamespace }}
- name: OPENEBS_IO_NFS_SERVER_NS
value: {{ .Values.nfsProvisioner.nfsServerNamespace }}
{{- end }}

# Process name used for matching is limited to the 15 characters
# present in the pgrep output.
# So fullname can't be used here with pgrep (>15 chars).A regular expression
Expand Down
3 changes: 3 additions & 0 deletions deploy/helm/charts/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ nfsProvisioner:
healthCheck:
initialDelaySeconds: 30
periodSeconds: 60
# namespace in which nfs server objects should be created
# By default, nfs provisioner will create these resources in nfs provisioner's namespace
# nfsServerNamespace: openebs

nfsStorageClass:
name: openebs-kernel-nfs
Expand Down
3 changes: 3 additions & 0 deletions deploy/kubectl/openebs-nfs-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ spec:
value: "true"
- name: OPENEBS_IO_INSTALLER_TYPE
value: "openebs-operator-nfs"
# OPENEBS_IO_NFS_SERVER_NS defines the namespace for nfs-server deployment
#- name: OPENEBS_IO_NFS_SERVER_NS
# value: "openebs"
# OPENEBS_IO_NFS_SERVER_IMG defines the nfs-server-alpine image name to be used
# while creating nfs volume
- name: OPENEBS_IO_NFS_SERVER_IMG
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,5 @@ require (
k8s.io/apimachinery v0.17.3
k8s.io/client-go v11.0.0+incompatible
k8s.io/klog v1.0.0
k8s.io/kubectl v0.0.0
sigs.k8s.io/sig-storage-lib-external-provisioner v4.1.0+incompatible
)
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,6 @@ k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLy
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-proxy v0.17.3/go.mod h1:ds8R8bUYPWtQlspC47Sff7o5aQhWDsv6jpQJATDuqaQ=
k8s.io/kube-scheduler v0.17.3/go.mod h1:36HgrrPqzK+rOLTRtDG//b89KjrAZqFI4PXOpdH351M=
k8s.io/kubectl v0.17.3 h1:9HHYj07kuFkM+sMJMOyQX29CKWq4lvKAG1UIPxNPMQ4=
k8s.io/kubectl v0.17.3/go.mod h1:NUn4IBY7f7yCMwSop2HCXlw/MVYP4HJBiUmOR3n9w28=
k8s.io/kubelet v0.17.3/go.mod h1:Nh8owUHZcUXtnDAtmGnip36Nw+X6c4rbmDQlVyIhwMQ=
k8s.io/kubernetes v1.17.3/go.mod h1:gt28rfzaskIzJ8d82TSJmGrJ0XZD0BBy8TcQvTuCI3w=
Expand Down
10 changes: 10 additions & 0 deletions provisioner/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ const (
// Note: If image name is not mentioned then provisioner.ProvisionerNFSServerImage
//
NFSServerImageKey menv.ENVKey = "OPENEBS_IO_NFS_SERVER_IMG"

// NFSServerNamespace defines the namespace for nfs server objects
// Default value is menv.OpenEBSNamespace(operator namespace)
NFSServerNamespace menv.ENVKey = "OPENEBS_IO_NFS_SERVER_NS"
)

var (
Expand All @@ -62,6 +66,12 @@ var (
func getOpenEBSNamespace() string {
return menv.Get(menv.OpenEBSNamespace)
}

// getNfsServerNamespace return namespace for nfs-server
func getNfsServerNamespace() string {
return menv.GetOrDefault(NFSServerNamespace, menv.Get(menv.OpenEBSNamespace))
}

func getDefaultExportsSC() string {
return menv.GetOrDefault(ProvisionerExportsSC, string(defaultExportsSC))
}
Expand Down
49 changes: 22 additions & 27 deletions provisioner/helper_kernel_nfs_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,19 @@ func (p *Provisioner) createBackendPVC(nfsServerOpts *KernelNFSServerOptions) er
//if the previous reconciliation of PVC-PV, resulted in
//creating a PVC, but was not yet available for 60+ seconds
_, err := persistentvolumeclaim.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(pvcName, metav1.GetOptions{})

if err == nil {
nfsServerOpts.pvcName = pvcName
klog.Infof("Volume %v has been initialized with PVC:%v", nfsServerOpts.pvName, pvcName)
klog.Infof("Volume %v has been initialized with PVC:%s/%s", nfsServerOpts.pvName, p.serverNamespace, pvcName)
return nil
}

//TODO
// Create PVC using the provided capacity and SC details
pvcObjBuilder := persistentvolumeclaim.NewBuilder().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
WithName(pvcName).
WithLabels(nfsServerOpts.getLabels()).
WithCapacity(nfsServerOpts.capacity).
Expand All @@ -125,13 +125,13 @@ func (p *Provisioner) createBackendPVC(nfsServerOpts *KernelNFSServerOptions) er
}

_, err = persistentvolumeclaim.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Create(pvcObj)

if err != nil {
//TODO : Need to relook at this error
//If the error is about PVC being already present, then return nil
return errors.Wrapf(err, "failed to create PVC{%v}", pvcName)
return errors.Wrapf(err, "failed to create PVC{%s/%s}", p.serverNamespace, pvcName)
}

nfsServerOpts.pvcName = pvcName
Expand All @@ -151,9 +151,8 @@ func (p *Provisioner) deleteBackendPVC(nfsServerOpts *KernelNFSServerOptions) er
//Check if the PVC still exists. It could have been removed
// or never created due to a provisioning create failure.
_, err := persistentvolumeclaim.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(pvcName, metav1.GetOptions{})

if err == nil {
nfsServerOpts.pvcName = pvcName
klog.Infof("Volume %v has been initialized with PVC:%v. Initiating delete...", nfsServerOpts.pvName, pvcName)
Expand All @@ -166,9 +165,8 @@ func (p *Provisioner) deleteBackendPVC(nfsServerOpts *KernelNFSServerOptions) er

// Delete PVC
err = persistentvolumeclaim.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Delete(pvcName, &metav1.DeleteOptions{})

if err != nil {
//TODO : Need to relook at this error
return errors.Errorf("unable to delete PVC %v associated with PV:%v", nfsServerOpts.pvName, pvcName)
Expand All @@ -190,12 +188,12 @@ func (p *Provisioner) createDeployment(nfsServerOpts *KernelNFSServerOptions) er
//if the previous reconciliation of PVC-PV, resulted in
//creating a Deployment, but was not yet available for 60+ seconds
_, err := deployment.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(deployName)

if err == nil {
nfsServerOpts.deploymentName = deployName
klog.Infof("Volume %v has been initialized with Deployment:%v", nfsServerOpts.pvName, deployName)
klog.Infof("Volume %v has been initialized with Deployment:%s/%s", nfsServerOpts.pvName, p.serverNamespace, deployName)
return nil
}

Expand All @@ -209,7 +207,7 @@ func (p *Provisioner) createDeployment(nfsServerOpts *KernelNFSServerOptions) er
// Create Deployment for NFS Server and mount the exports PVC.
deployObjBuilder := deployment.NewBuilder().
WithName(deployName).
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
WithLabelsNew(nfsDeployLabelSelector).
WithSelectorMatchLabelsNew(nfsDeployLabelSelector).
WithStrategyTypeRecreate().
Expand Down Expand Up @@ -280,7 +278,7 @@ func (p *Provisioner) createDeployment(nfsServerOpts *KernelNFSServerOptions) er
}

_, err = deployment.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Create(deployObj)

if err != nil {
Expand All @@ -306,9 +304,8 @@ func (p *Provisioner) deleteDeployment(nfsServerOpts *KernelNFSServerOptions) er
//Check if the Deploy still exists. It could have been removed
// or never created due to a provisioning create failure.
_, err := deployment.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(deployName)

if err == nil {
nfsServerOpts.deploymentName = deployName
klog.Infof("Volume %v has been initialized with Deployment:%v. Initiating delete...", nfsServerOpts.pvName, deployName)
Expand All @@ -321,9 +318,8 @@ func (p *Provisioner) deleteDeployment(nfsServerOpts *KernelNFSServerOptions) er

// Delete PVC
err = deployment.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Delete(deployName, &metav1.DeleteOptions{})

if err != nil {
//TODO : Need to relook at this error
return errors.Errorf("unable to delete deployment %v associated with PV:%v", nfsServerOpts.pvName, deployName)
Expand All @@ -346,7 +342,7 @@ func (p *Provisioner) createService(nfsServerOpts *KernelNFSServerOptions) error
//if the previous reconciliation of PVC-PV, resulted in
//creating a Service, but was not yet available for 60+ seconds
_, err := service.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(svcName, metav1.GetOptions{})

if err == nil {
Expand All @@ -362,7 +358,7 @@ func (p *Provisioner) createService(nfsServerOpts *KernelNFSServerOptions) error
//TODO
// Create Service
svcObjBuilder := service.NewBuilder().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
WithName(svcName).
WithPorts(
[]corev1.ServicePort{
Expand All @@ -386,7 +382,7 @@ func (p *Provisioner) createService(nfsServerOpts *KernelNFSServerOptions) error
}

_, err = service.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Create(svcObj)

if err != nil {
Expand All @@ -413,12 +409,11 @@ func (p *Provisioner) deleteService(nfsServerOpts *KernelNFSServerOptions) error
//Check if the Serivce still exists. It could have been removed
// or never created due to a provisioning create failure.
_, err := service.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(svcName, metav1.GetOptions{})

if err == nil {
nfsServerOpts.serviceName = svcName
klog.Infof("Volume %v has been initialized with Service:%v. Initiating delete...", nfsServerOpts.pvName, svcName)
klog.Infof("Volume %s has been initialized with Service:%s/%s. Initiating delete...", nfsServerOpts.pvName, p.serverNamespace, svcName)
} else {
return nil
}
Expand All @@ -428,12 +423,12 @@ func (p *Provisioner) deleteService(nfsServerOpts *KernelNFSServerOptions) error

// Delete Service
err = service.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Delete(svcName, &metav1.DeleteOptions{})

if err != nil {
//TODO : Need to relook at this error
return errors.Errorf("unable to delete Service %v associated with PV:%v", nfsServerOpts.pvName, svcName)
return errors.Errorf("unable to delete Service %s/%s associated with PV:%s", p.serverNamespace, svcName, nfsServerOpts.pvName)
}

return nil
Expand All @@ -455,7 +450,7 @@ func (p *Provisioner) getNFSServerAddress(nfsServerOpts *KernelNFSServerOptions)
if p.useClusterIP {
//nfsService := nil
nfsService, err := service.NewKubeClient().
WithNamespace(p.namespace).
WithNamespace(p.serverNamespace).
Get(nfsServerOpts.serviceName, metav1.GetOptions{})
if err != nil || nfsService == nil {
return "", errors.Wrapf(err, "failed to get NFS Service for PVC{%v}", nfsServerOpts.pvcName)
Expand All @@ -465,7 +460,7 @@ func (p *Provisioner) getNFSServerAddress(nfsServerOpts *KernelNFSServerOptions)

// Return the cluster local nfs service ip
// <service-name>.<namespace>.svc.cluster.local
return nfsServerOpts.serviceName + "." + p.namespace + ".svc.cluster.local", nil
return nfsServerOpts.serviceName + "." + p.serverNamespace + ".svc.cluster.local", nil
}

// createNFSServer creates the NFS Server deployment and related
Expand Down
6 changes: 4 additions & 2 deletions provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ func NewProvisioner(stopCh chan struct{}, kubeClient *clientset.Clientset) (*Pro
return nil, fmt.Errorf("Cannot start Provisioner: failed to get namespace")
}

nfsServerNs := getNfsServerNamespace()
p := &Provisioner{
stopCh: stopCh,

kubeClient: kubeClient,
namespace: namespace,
kubeClient: kubeClient,
namespace: namespace,
serverNamespace: nfsServerNs,
defaultConfig: []mconfig.Config{
{
Name: KeyPVNFSServerType,
Expand Down
15 changes: 13 additions & 2 deletions provisioner/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,25 @@ import (
//Provisioner struct has the configuration and utilities required
// across the different work-flows.
type Provisioner struct {
stopCh chan struct{}
stopCh chan struct{}

kubeClient *clientset.Clientset
namespace string

// namespace in which provisioner is running
namespace string

// serverNamespace in which nfs server deployments gets created
// can be set through env variable NFS_SERVER_NAMESPACE
// default value is Provisioner.namespace
serverNamespace string

// defaultConfig is the default configurations
// provided from ENV or Code
defaultConfig []mconfig.Config

// getVolumeConfig is a reference to a function
getVolumeConfig GetVolumeConfigFn

//determine if clusterIP or clusterDNS should be used
useClusterIP bool
}
Expand Down
Loading

0 comments on commit e0a9e18

Please sign in to comment.