Click here to Skip to main content
15,886,676 members
Articles / Programming Languages / C#

Access Control for EMC Isilon OneFS 7.2 API using C# .NET

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
1 Feb 2015CPOL5 min read 12.1K   1  
Introduction to using the Isilon OneFS REST API using C# .NET to create access points, grant users access, and file system queries

Introduction

This article dives a little deeper into using the Isilon OneFS 7.2 REST API using C# .NET. It focuses on namespace (File/Folder) access using the API. This article will cover how to enable file system access, create access points, create users and access control lists (ACLs), and basic file system queries.

Background

I was working on several automation and visualization applications for EMC's Isilon scale out NAS platform and couldn't find much information about how to access the API in .NET. In my first article, EMC Isilon OneFS REST API using C# .NET, I covered the basics about how to connect to, authenticate, and query data from an Isilon cluster, as well as basic JSON de-serialization of the responses into .NET objects. Please refer to my previous article to get started.

File System Access

Accessing files and folders on an Isilon cluster using the OneFS API is similar to how you would access files and folders using SMB or NFS protocols. At the base, you need an access point, which is similar to a CIFS share or an NFS mount point. Starting out, only the root user will have access to the file system, so you will need to use the root account to create users, access points, and grant access.

Get Namespaces

Authenticating against the cluster using the root account (root@clustername), you can use the /namespace/ resource to obtain a list of all access points that root has access to. In the beginning, it should only be the /ifs/ access point. 

First, we want to authenticate to the cluster using the root credentials (see the previous article on how to obtain a session cookie). Afterwards, we will want to do a HTTP GET request to the /namespace/ resource to get a list of all access points.

C#
ResourceString = "/namespace/";

// Create a web request object pointing to the Isilon server and Resource String
request = (HttpWebRequest)WebRequest.Create(IsilonServerAddress + ResourceString);

// Set the cookie we received onto the request object
request.Headers.Add("Cookie", cookie);

response = (HttpWebResponse)request.GetResponse();

And here is the json response from this GET query.

C#
{"namespaces":[{
   "name" : "ifs",
   "path" : "/ifs"
}
]}

Here are the classes I use to de-serialize the json response into .NET objects.

C#
[DataContract]
public class IsilonNamespaceResponse
{
    [DataMember(Name = "namespaces")]
    public Namespace[] AccessPoints;
}

[DataContract]
public class Namespace
{
    [DataMember(Name = "name", IsRequired = true)]
    public string Name;

    [DataMember(Name = "path", IsRequired = true)]
    public string Path;
}

Finally, we create our .NET object:

C#
    DataContractJsonSerializer js = 
           new DataContractJsonSerializer(typeof(IsilonNamespaceResponse));
    IsilonNamespaceResponse members = 
           (IsilonNamespaceResponse)js.ReadObject(response.GetResponseStream());

    foreach(Namespace accessPoint in members.AccessPoints)
    {
        // Do something against the access point
    }

Creating Access Points

In some applications, it may make sense to use the main access point /ifs/, however this will grant access to the entire OneFS file system, so it is highly recommended that applications written to use the API for file system access use an alternate access point. To create an access point, you will need to preform an HTTP PUT request to the /namespace/ resource. The format of the request will be /namespace/*NewAccessPointName*<name access="" create="" new="" of="" point="" to="">, and the body of the request will be a JSON object with the absolute path within the OneFS file system to the access point.

The request should look like this:

C#
PUT /namespace/accesspoint1 HTTP/1.1 Host my_cluster:8080 
Date: Fri, 15 Mar 2013 21:51:50 GMT 
Content-Type: text/xml    
{      
    "path": "/ifs/home/"    
}

In this case, I want to create an access point called "MyAccessPoint" and point it to a folder on the OneFS file system called Share1. I have created this folder on my Isilon cluster:

Image 1

Note: The absolute path on the file system MUST exist before you create an access point using it. Otherwise, the command will return a HTTP 400 message.

To create the access point, first I need a class to represent the json object that we will send to the cluster:

C#
[DataContract]
public class AccessPoint
{
    [DataMember(Name = "path")]
    public string AbsolutePath;
}

Next, I need to create an instance of this class and give the "path" property an absolute path into the file system. As well, I need to specify the access point name in the request string. Finally, I need to serialize that object out to the RequestStream of an HTTP PUT request object.

C#
string AccessPointName = "MyAccessPoint";

AccessPoint MyAccessPoint = new AccessPoint();
MyAccessPoint.AbsolutePath = "/ifs/Share1";

ResourceString = "/namespace/" + AccessPointName;

// Create a web request object pointing to the Isilon server and Resource String
request = (HttpWebRequest)WebRequest.Create(IsilonServerAddress + ResourceString);
request.Method = "PUT";
request.ContentType = "text/xml"; // Not sure why xml, but that's what this request needs?

// Set the cookie we received onto the request object
request.Headers.Add("Cookie", cookie);

// Write the AccessPoint object to the request stream
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(AccessPoint));
js.WriteObject(request.GetRequestStream(), MyAccessPoint);

// Should just be an 200 OK response... If not, something failed!
response = (HttpWebResponse)request.GetResponse();

User Access

Now that we have an access point, we'll want to manage the user permissions to that access point. (In other words, don't use the root account for production file system access within your applications!). First, we need to create a user, and unfortunately I don't see a way to do this through the API, though if I find it, I will modify this article. However, you can use the GUI or the CLI to create a user. For instance, using the CLI, use the following command:

C#
isi auth users create user1 --password user1 --home-directory /ifs/ home/user1 --password-expires no

After we have our user created, we can grant those user permissions to that access point. The json object we would need to pass is this:

C#
{
   "authoritative":"acl", 
   "acl":
   [{
     "trustee": 
     {
        "name":"user1",
        "type":"user"
     }, 
     "accesstype":"allow", 
     "accessrights":["file_read"], 
     "op":"add"
   }]
}

First, here are the .NET classes needed to create this json object:

C#
// Trustee object (User or Group)
[DataContract]
public class Trustee
{
    [DataMember(Name = "name")]
    public string UserName;

    [DataMember(Name = "type")]
    public string UserType;
}

// The ACL which specifies Trustee, type of access, rights, and the operation (add, remove)
[DataContract]
public class AccessControlList
{
    [DataMember(Name = "trustee")]
    public Trustee Trustee;

    [DataMember(Name = "accesstype")]
    public string AccessType;

    [DataMember(Name = "accessrights")]
    public string[] AccessRights;

    [DataMember(Name = "op")]
    public string Operation;
}

// The request to create an ACL
[DataContract]
public class CreateACL
{
    [DataMember(Name = "authoritative")]
    public string authoritative = "acl";

    [DataMember(Name = "acl")]
    public AccessControlList[] acl;
}

Now, we will need to create the ACL, trustee, and request object to pass to the Isilon cluster. You will need to create an HTTP PUT command, and pass the json object against the Access Point with the following query parameters - acl, and nsaccess, which will look like this: "PUT /namespace/<access_point>?acl&nsaccess=true" The nsaccess parameter is used to indicate that the requested operation is on the access point itself, instead of the store path. The value must be set to true, otherwise the request will behave similarly to a get or put operation against the data within the access point.

The following code creates the .NET object that we will use to send to the Isilon cluster:

C#
Trustee trustee = new Trustee();
trustee.UserName = "user1"; // Specify the user we created above
trustee.UserType = "user"; // user or group?

AccessControlList acl = new AccessControlList();
acl.Trustee = trustee;
acl.Operation = "add";
acl.AccessType = "allow";
acl.AccessRights = new string[] { "file_read" };

CreateACL createAcl = new CreateACL();
createAcl.acl = new AccessControlList[] { acl };

Now let's pass our object to the Isilon cluster:

C#
string AccessPointName = "MyAccessPoint";

ResourceString = "/namespace/" + AccessPointName + "?acl&nsaccess=true";

// Create a web request object pointing to the Isilon server and Resource String
request = (HttpWebRequest)WebRequest.Create(IsilonServerAddress + ResourceString);
request.Method = "PUT";
request.ContentType = "application/json";

// Set the cookie we received onto the request object
request.Headers.Add("Cookie", cookie);

// Write the CreateACL object to the request stream
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(CreateACL));
js.WriteObject(request.GetRequestStream(), createAcl);

// Should just be an 200 OK response... If not, something failed!
response = (HttpWebResponse)request.GetResponse();

Assuming this succeeds, we can then turn around and do a GET request against the access point, specifying the acl & nsaccess=true parameters to get a list of all ACLs on our access point. In other words, GET /namespace/MyAccessPoint?acl&nsaccess=true which will return something like this:

C#
{
"acl" : 
[

{
"accessrights" : [ "file_read" ]

"accesstype" : "allow",
"inherit_flags" : [],
"trustee" : 
{
"id" : "UID:2000",
"name" : "user1",
"type" : "user"
}
}
],
"authoritative" : "acl",
"group" : 
{
"id" : "GID:0",
"name" : "wheel",
"type" : "group"
},
"mode" : "0040",
"owner" : 
{
"id" : "UID:0",
"name" : "root",
"type" : "user"
}
}

And as you can see, user1 is now granted read only access to the access point.

Directory Operations

Now that our user has access to the access point, there's a lot of things you can do from an API perspective. The basic operation is to request a list of all objects within that access point (Files and Folders). For demonstration, I populated my access point with several documents and folders.

Image 2

To access the information within the access point, remove the acl & nsaccess=true parameters from the query string, and what returns is a list of all the objects within that access point:

C#
{"children":[{
   "name" : "Notepad.txt"
}
,{
   "name" : "MS Word Document.docx"
}
,{
   "name" : "MS Excel Spreadsheet.xlsx"
}
,{
   "name" : "MS Power Point Presentation.pptx"
}
,{
   "name" : "Folder1"
}
]}

Conclusion

This is an example of how you can use the Isilon OneFS API to do access point, access control, and file system access using .NET. Hope you found this information useful!

History

  • Feb-2015: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Systems Engineer EMC
United States United States
Systems Engineer and Software Developer

Comments and Discussions

 
-- There are no messages in this forum --