Openstack.Net SDK cannot access service with region

♀尐吖头ヾ 提交于 2019-12-02 10:13:09

I managed to extend the functionality of the Openstack.Net SDK fairly simply. The code below extends it to include various functions for Tenant/Project manipulations...

Firstly, create a NewTenant container that will be used to pass data to and from the webservices, I've put it in the same namespace as the others...

using Newtonsoft.Json;

namespace net.openstack.Core.Domain
{

    [JsonObject(MemberSerialization.OptIn)]
    public class NewTenant
    {
        /// <summary>
        /// Gets the ID for the new user.
        /// <note type="warning">The value of this property is not defined. Do not use.</note>
        /// </summary>
        [JsonProperty("id", DefaultValueHandling = DefaultValueHandling.Include)]
        public string Id { get; private set; }

        [JsonProperty("name")]
        public string Name { get; private set; }

        [JsonProperty("description")]
        public string Description { get; private set; }

        [JsonProperty("enabled")]
        public bool Enabled { get; private set; }

        public NewTenant(string name, string description, bool enabled = true)
        {
            Name = name;
            Description = description;
            Enabled = enabled;
        }
    }
}

Now we can create any new Request classes for posting the data...

using System;
using Newtonsoft.Json;
using net.openstack.Core.Domain;

namespace net.openstack.Core.Request
{

    [JsonObject(MemberSerialization.OptIn)]
    internal class AddTenantRequest
    {
        [JsonProperty("tenant")]
        public NewTenant Tenant { get; private set; }

        public AddTenantRequest(NewTenant tenant)
        {
            if (tenant == null)
                throw new ArgumentNullException("tenant");

            Tenant = tenant;
        }
    }
}

Now create the Response objects for the requests to help retrieve the data

using net.openstack.Core.Domain;
using Newtonsoft.Json;

namespace net.openstack.Core.Response
{
    [JsonObject(MemberSerialization.OptIn)]
    internal class NewTenantResponse
    {
        [JsonProperty("tenant")]
        public NewTenant NewTenant { get; private set; }
    }

    [JsonObject(MemberSerialization.OptIn)]
    internal class TenantResponse
    {
        [JsonProperty("tenant")]
        public Tenant Tenant { get; private set; }
    }
}

Now we can create a class that inherits from OpenStackIdentityProvider with the additional functionality for Tenant/Project manipulation that we want...

using System;
using System.Net;
using JSIStudios.SimpleRESTServices.Client;
using net.openstack.Core.Domain;
using net.openstack.Core.Request;
using net.openstack.Core.Response;

namespace net.openstack.Core.Providers
{
    public class ExtendedOpenStackIdentityProvider : OpenStackIdentityProvider
    {
        public ExtendedOpenStackIdentityProvider(Uri urlBase)
            : base(urlBase)
        {
        }

        public ExtendedOpenStackIdentityProvider(Uri urlBase, CloudIdentity identity)
            : base(urlBase, identity)
        {
        }

        public ExtendedOpenStackIdentityProvider(Uri urlBase, JSIStudios.SimpleRESTServices.Client.IRestService restService, net.openstack.Core.Caching.ICache<UserAccess> tokenCache)
            : base(urlBase, restService, tokenCache)
        {
        }

        public ExtendedOpenStackIdentityProvider(Uri urlBase, CloudIdentity identity, JSIStudios.SimpleRESTServices.Client.IRestService restService, net.openstack.Core.Caching.ICache<UserAccess> tokenCache)
            : base(urlBase, identity, restService, tokenCache)
        {
        }

        public NewTenant AddTenant(NewTenant tenant, CloudIdentity identity)
        {
            if (tenant == null)
                throw new ArgumentNullException("tenant");
            if (string.IsNullOrEmpty(tenant.Name))
                throw new ArgumentException("tenant.Name cannot be null or empty");
            if (tenant.Id != null)
                throw new InvalidOperationException("tenant.Id must be null");

            CheckIdentity(identity);

            var response = ExecuteRESTRequest<NewTenantResponse>(identity, new Uri(UrlBase, "/v2.0/tenants"), HttpMethod.POST, new AddTenantRequest(tenant));

            if (response == null || response.Data == null)
                return null;

            return response.Data.NewTenant;
        }

        public Tenant GetTenant(string tenantId, CloudIdentity identity)
        {
            if (tenantId == null)
                throw new ArgumentNullException("tenantId");

            CheckIdentity(identity);

            var urlPath = string.Format("v2.0/tenants/{0}", tenantId);

            var response = ExecuteRESTRequest<TenantResponse>(identity, new Uri(UrlBase, urlPath), HttpMethod.GET);

            if (response == null || response.Data == null)
                return null;

            return response.Data.Tenant;
        }

        public bool DeleteTenant(string tenantId, CloudIdentity identity)
        {
            if (tenantId == null)
                throw new ArgumentNullException("tenantId");
            if (string.IsNullOrEmpty(tenantId))
                throw new ArgumentException("tenantId cannot be empty");
            CheckIdentity(identity);

            var urlPath = string.Format("v2.0/tenants/{0}", tenantId);
            var response = ExecuteRESTRequest(identity, new Uri(UrlBase, urlPath), HttpMethod.DELETE);

            if (response != null && response.StatusCode == HttpStatusCode.NoContent)
                return true;

            return false;
        }

        public bool AddTenantUserRole(string tenantId, string userId, string roleId, CloudIdentity identity)
        {
            if (tenantId == null)
                throw new ArgumentNullException("tenantId");
            if (string.IsNullOrEmpty(tenantId))
                throw new ArgumentException("tenantId cannot be empty");
            if (userId == null)
                throw new ArgumentNullException("userId");
            if (string.IsNullOrEmpty(userId))
                throw new ArgumentException("userId cannot be empty");
            if (roleId == null)
                throw new ArgumentNullException("roleId");
            if (string.IsNullOrEmpty(roleId))
                throw new ArgumentException("roleId cannot be empty");

            CheckIdentity(identity);

            var urlPath = string.Format("v2.0/tenants/{0}/users/{1}/roles/OS-KSADM/{2}", tenantId, userId, roleId);
            var response = ExecuteRESTRequest(identity, new Uri(UrlBase, urlPath), HttpMethod.PUT);

            if (response != null && response.StatusCode == HttpStatusCode.NoContent)
                return true;

            return false;
        }
    }
}

I imagine that this functionality will appear in the GitHub version soon, but if not I hope it's useful.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!