0 Replies Latest reply on Oct 21, 2015 10:00 AM by Alex_Maxwell

    (.NET SDK) Query service returns operation denied unless user is a system admin

    Alex_Maxwell Lurker

      I am trying to get a list of vapps owned by a user. I'm logging in with an Organization Admin user. If I use a system admin, it works fine.  VCD: 5.5.2.2000523, vcloud .NET SDK 5.5.0.0

       

      Sample:

       

      public bool GetVAppsForUser(string username) {

                  bool hadError = false;

                  client.Login("OrgAdmin", "Password");  // client is of type vCloudClient

                  VcloudAdminExtension adminExtension = client.GetVcloudAdminExtension();

                  ExtensionQueryService queryService = adminExtension.GetExtensionQueryService();

       

                  // Sort by name, ascending

                  Dictionary<QueryAdminVAppField, SortType> sortFields = new Dictionary<QueryAdminVAppField, SortType>();

                  sortFields.Add(QueryAdminVAppField.NAME, SortType.SORT_ASC);

                            

                  List<QueryAdminVAppField> fields = new List<QueryAdminVAppField>();

                  fields.Add(QueryAdminVAppField.NAME);

                  fields.Add(QueryAdminVAppField.ORG);

                  fields.Add(QueryAdminVAppField.OWNERNAME);

       

                  // Filter for all owned by user, adding an asterisk makes the comparison case-insensitive

                  Expression expression = new Expression(QueryAdminVAppField.OWNERNAME, username + "*", ExpressionType.EQUALS);

                  Filter filter = new Filter(expression);

       

                  QueryParams<QueryAdminVAppField> queryParams = new QueryParams<QueryAdminVAppField>();

                  queryParams.PageSize = 1000;

                  queryParams.Page = 1;

                  queryParams.Filter = filter;

                  queryParams.Fields = fields;

       

                  RecordResult<QueryResultAdminVAppRecordType> recordResult = queryService.QueryAllVappRecords(queryParams);

       

                  foreach (QueryResultAdminVAppRecordType vappRecord in recordResult.GetRecords())

                  {  /* Do stuff with vappRecord */ }

       

                   return hadError;

      }

       

       

      Debug output:
      ClientAppTrace Information: 0 : Status Code - 403
      ClientAppTrace Information: 0 : Status - Forbidden
      ClientAppTrace Information: 0 : Response - <?xml version="1.0" encoding="UTF-8"?>
      <Error xmlns="http://www.vmware.com/vcloud/v1.5" minorErrorCode="ACCESS_TO_RESOURCE_IS_FORBIDDEN" message="This operation is denied." majorErrorCode="403" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://10.101.6.62/api/v1.5/schema/master.xsd"></Error>

       

       

      Is there a way to narrow it down to a specific organization? Or combining Expression objects (ideally filter=(ownerName==somename*;organizationName=myorg) )? The user (somename) only has one vapp, in the same org as the Org Admin I'm using to perform the query. I tried filtering for all vapps in the org, and I got the same result, so I'm not sure why it gives me a 403. 

       

      Has anybody gotten the query service to work with just an Org Admin? Oh, I'm doing it this way instead of  Vdc.GetVdcByReference(x,y).GetVappRefs()) because the query service is much faster.

       

              public bool GetVAppsForUser(string username)

       

              {

       

                  //bool answer = false;

       

                  //Vdc vdc = FindVdc(orgname, vdcname);

       

                  int numVapps = 0;

       

                  int vAppsCleared = 0;

       

       

                  bool hadError = false;

       

                 

       

                

       

                  Dictionary<string, ReferenceType> organizationsMap = client.GetOrgRefsByName();   

       

                  Dictionary<string, string> hrefToOrg = new Dictionary<string, string>();

       

                  foreach (string orgName in organizationsMap.Keys)

       

                  {

       

                      hrefToOrg[organizationsMap[orgName].href] = orgName;

       

                  }

       

       

                  VcloudAdminExtension adminExtension = client.GetVcloudAdminExtension();

       

                  ExtensionQueryService queryService = adminExtension.GetExtensionQueryService();

       

       

                  // Sort by name, ascending

       

                  Dictionary<QueryAdminVAppField, SortType> sortFields = new Dictionary<QueryAdminVAppField, SortType>();

       

                  sortFields.Add(QueryAdminVAppField.NAME, SortType.SORT_ASC);

       

       

                  // not sure why we need fields, but we'll take them.

       

                  List<QueryAdminVAppField> fields = new List<QueryAdminVAppField>();

       

                  fields.Add(QueryAdminVAppField.NAME);

       

                  fields.Add(QueryAdminVAppField.ORG);

       

                  fields.Add(QueryAdminVAppField.OWNERNAME);

       

                  //fields.Add(QueryAdminVAppField.HREF);

       

       

                  // Filter for all owned by user

       

                  // Adding an asterisk makes the comparison case-insensitive

       

                  Expression expression = new Expression(QueryAdminVAppField.OWNERNAME, username + "*", ExpressionType.EQUALS);

       

                  //Expression orgFilter = new Expression(QueryAdminVAppField.ORG, "Engineering", ExpressionType.EQUALS);

       

                  Filter filter = new Filter(expression);

       

                 

       

                  QueryParams<QueryAdminVAppField> queryParams = new QueryParams<QueryAdminVAppField>();

       

                  queryParams.PageSize = 1000;

       

                  queryParams.Page = 1;

       

                  queryParams.Filter = filter;

       

                  queryParams.Fields = fields;

       

                     

       

                  RecordResult<QueryResultAdminVAppRecordType>  recordResult = queryService.QueryAllVappRecords(queryParams);

       

       

                  Dictionary<string, List<string>> vappsByOrganization = new Dictionary<string, List<string>>();

       

                  //Dictionary<string, ReferenceType> vAppReferencesByName = new Dictionary<string, ReferenceType>();

       

                  foreach (QueryResultAdminVAppRecordType vappRecord in recordResult.GetRecords())

       

                  {

       

                      // it's easier to transform the href into a reference.id with string replacement, rather than

       

                      // getting the reference, then tracking down the organization.

       

                      string lastPart = vappRecord.href.Substring(vappRecord.href.LastIndexOf("/") + "/vapp-".Length);

       

                      string vcloud_id = "urn:vcloud:vapp:" + lastPart;

       

                      string orgName = vappRecord.org; 

       

                      if (!hrefToOrg.ContainsKey(vappRecord.org))

       

                          // If we can't find an org name in the the organizationMap, we'll just use the href we get from the vappRecord

       

                          log.ErrorFormat("Can't find organization name for vapp {0}. Org href is {1}.  This shouldn't happen.", vappRecord.name, vappRecord.org);                   

       

                      else

       

                          orgName = hrefToOrg[vappRecord.org];

       

                         

       

                      log.Debug("\t\towner: " + vappRecord.ownerName + ", vapp: " + vappRecord.name + ", vcloud id: " + vcloud_id + ", org: " + vappRecord.org);

       

                      numVapps++;

       

                      if (!vappsByOrganization.Keys.Contains(orgName))

       

                      {

       

                          vappsByOrganization.Add(orgName, new List<string>());

       

                      }

       

       

                      vappsByOrganization[orgName].Add(vappRecord.name);

       

       

                      if (checkForVapp(vappRecord.name, vcloud_id, orgName))

       

                      {

       

                          vAppsCleared++;

       

                      }

       

       

                        

       

                                         

       

       

       

                  }

       

                  log.Debug("\tCheck for vapps in DB that don't exist in this cloud");

       

                  foreach (string org in vappsByOrganization.Keys)

       

                  {

       

                      if (!markOrphanedAsDeleted(vappsByOrganization[org], username, org))

       

                          vAppsCleared--;

       

                  }

       

                     

       

                    

       

                 

       

       

                  return numVapps == vAppsCleared;

       

              }