Repository: vmware/govmomi
Pull request #2254 (2021-01-25 19:40:01)

Update volume ACL spec to add delete field
This PR is a minor change to update the volume ACL spec to add delete field. This is needed to revoke/remove permissions for a given volume.


```
$ go test -v
=== RUN   TestClient
    client_test.go:682: Creating CNS file volume using the spec: {DynamicData:{} Name:pvc-file-share-volume VolumeType:FILE Datastores:[Datastore:datastore-42] Metadata:{DynamicData:{} ContainerCluster:{DynamicData:{} ClusterType:KUBERNETES ClusterId:demo-cluster-id VSphereUser:Administrator@vsphere.local ClusterFlavor:VANILLA ClusterDistribution:OpenShift} EntityMetadata:[] ContainerClusterArray:[{DynamicData:{} ClusterType:KUBERNETES ClusterId:demo-cluster-id VSphereUser:Administrator@vsphere.local ClusterFlavor:VANILLA ClusterDistribution:OpenShift}]} BackingObjectDetails:0xc0003689c0 Profile:[] CreateSpec:0xc000364c80}
    client_test.go:707: Fileshare volume created sucessfully. filevolumeId: file:d71f42e7-ba28-4fa7-9d95-1fef4c43978d
    client_test.go:741: Invoking ConfigureVolumeACLs using the spec: types.CnsVolumeACLConfigureSpec{
            VolumeId: types.CnsVolumeId{
                Id: "file:d71f42e7-ba28-4fa7-9d95-1fef4c43978d",
            },
            AccessControlSpecList: []types.CnsNFSAccessControlSpec{
                {
                    Permission: []types.VsanFileShareNetPermission{
                        {Ips:"192.168.124.2", Permissions:"READ_ONLY", AllowRoot:false},
                    },
                    Delete: false,
                },
            },
        }
    client_test.go:782: Invoking ConfigureVolumeACLs using the spec: types.CnsVolumeACLConfigureSpec{
            VolumeId: types.CnsVolumeId{
                Id: "file:d71f42e7-ba28-4fa7-9d95-1fef4c43978d",
            },
            AccessControlSpecList: []types.CnsNFSAccessControlSpec{
                {
                    Permission: []types.VsanFileShareNetPermission{
                        {Ips:"192.168.124.2", Permissions:"READ_ONLY", AllowRoot:false},
                    },
                    Delete: true,
                },
            },
        }
--- PASS: TestClient (46.57s)
PASS
ok      github.com/vmware/govmomi/cns   46.589s
```

Verified by mounting the file volume and adding a file with read-only permission:
```
root [ / ]# mount -v -t nfs -o rw,vers=4.1 172.16.10.10:/vsanfs/52bf3d28-2682-63ff-b1c5-04d7ee5a6a32 /test
mount.nfs: timeout set for Mon Jan 25 21:58:30 2021
mount.nfs: trying text-based options 'vers=4.1,addr=172.16.10.10,clientaddr=192.0.254.4'
root [ / ]# touch test/chethan-test.txt
touch: cannot touch 'test/chethan-test.txt': Read-only file system
```


Ran the revoke permission test and mounted the volume and verified write operations:
```
root [ / ]# mount -v -t nfs -o rw,vers=4.1 172.16.10.10:/vsanfs/5249b0e0-a4c6-5660-8586-bc0611c47d0c /test 
mount.nfs: timeout set for Mon Jan 25 21:50:51 2021
mount.nfs: trying text-based options 'vers=4.1,addr=172.16.10.10,clientaddr=192.0.254.4'
root [ / ]# touch test/chethan-test.txt
```




chethanv28: cc: @divyenpatel Can you help with reviews and approvals
chethanv28: cc: @dougm PTAL. I missed this optional field in one of the previous PRs.
Thanks
divyenpatel: /approve

Patch:
diff --git a/cns/types/types.go b/cns/types/types.go
index f79c0157..16ed0c2a 100644
--- a/cns/types/types.go
+++ b/cns/types/types.go
@@ -624,6 +624,7 @@ type CnsVolumeACLConfigureSpec struct {
 type CnsNFSAccessControlSpec struct {
 	types.DynamicData
 	Permission []vsanfstypes.VsanFileShareNetPermission `xml:"netPermission,omitempty,typeattr"`
+	Delete     bool                                     `xml:"delete,omitempty"`
 }
 
 func init() {
diff --git a/scripts/govc-env.bash b/scripts/govc-env.bash
index 0def0b65..ed5fb2fc 100644
--- a/scripts/govc-env.bash
+++ b/scripts/govc-env.bash
@@ -44,17 +44,13 @@ govc-env() {
     for VAR in $(env | grep ^GOVC_ | cut -d= -f1); do
       echo "export ${VAR}='${!VAR}'"
     done
- 
+
     return
   fi
 
   # Save current environment
   if [ "$1" == "--save" ]; then
-    if [ ! -z "$2" ]; then
-    	govc-env > ${_govc_env_dir}/$2 && echo govc env has been saved to ${_govc_env_dir}/$2
-    else
-	echo Usage: govc-env --save configname
-    fi
+    govc-env > ${_govc_env_dir}/$2
     return
   fi
 


Test patch:
diff --git a/cns/client_test.go b/cns/client_test.go
index 0a400fb9..7f25bf6b 100644
--- a/cns/client_test.go
+++ b/cns/client_test.go
@@ -720,7 +720,7 @@ func TestClient(t *testing.T) {
 		fileBackingInfo := queryResult.Volumes[0].BackingObjectDetails.(*cnstypes.CnsVsanFileShareBackingDetails)
 		t.Logf("File Share Name: %s with accessPoints: %+v", fileBackingInfo.Name, fileBackingInfo.AccessPoints)
 
-		// Test Configure ACLs
+		// Test add read-only permissions using Configure ACLs
 		netPerms := make([]vsanfstypes.VsanFileShareNetPermission, 0)
 		netPerms = append(netPerms, vsanfstypes.VsanFileShareNetPermission{
 			Ips:         "192.168.124.2",
@@ -760,6 +760,44 @@ func TestClient(t *testing.T) {
 			t.FailNow()
 		}
 
+		// Test to revoke all permissions using Configure ACLs
+		netPerms = make([]vsanfstypes.VsanFileShareNetPermission, 0)
+		netPerms = append(netPerms, vsanfstypes.VsanFileShareNetPermission{
+			Ips:         "192.168.124.2",
+			Permissions: "READ_ONLY",
+		})
+
+		vSanNFSACLEntry = make([]cnstypes.CnsNFSAccessControlSpec, 0)
+		vSanNFSACLEntry = append(vSanNFSACLEntry, cnstypes.CnsNFSAccessControlSpec{
+			Permission: netPerms,
+			Delete:     true,
+		})
+
+		aclSpec = cnstypes.CnsVolumeACLConfigureSpec{
+			VolumeId:              volumeID,
+			AccessControlSpecList: vSanNFSACLEntry,
+		}
+		t.Logf("Invoking ConfigureVolumeACLs using the spec: %+v", pretty.Sprint(aclSpec))
+		aclTask, err = cnsClient.ConfigureVolumeACLs(ctx, aclSpec)
+		if err != nil {
+			t.Errorf("Failed to configure VolumeACLs. Error: %+v", err)
+			t.Fatal(err)
+		}
+		aclTaskInfo, err = GetTaskInfo(ctx, aclTask)
+		if err != nil {
+			t.Errorf("Failed to configure VolumeACLs. Error: %+v", err)
+			t.Fatal(err)
+		}
+		aclTaskResult, err = GetTaskResult(ctx, aclTaskInfo)
+		if err != nil {
+			t.Errorf("Failed to configure VolumeACLs. Error: %+v", err)
+			t.Fatal(err)
+		}
+		if aclTaskResult == nil {
+			t.Fatalf("Empty configure VolumeACLs task results")
+			t.FailNow()
+		}
+
 		// Test Deleting vSAN file-share Volume
 		var fileVolumeIDList []cnstypes.CnsVolumeId
 		fileVolumeIDList = append(fileVolumeIDList, cnstypes.CnsVolumeId{Id: filevolumeId})