0

独自のハードウェアを使用して、すべてのコンポーネントにバニラ オープンスタックをインストールしましたが、リージョンの問題により、ID 以外のサービスへのアクセスに問題があります。使用されるコードは、作成した管理者アカウントと管理者テナントで次のように呼び出されます...

    public static void TestAccess(string userName, string password, string projectName, string projectId)
    {
        try
        {
            Uri baseUrl = new Uri(URL_IDENTITY);

            CloudIdentityWithProject projectCloudId = new CloudIdentityWithProject();
            projectCloudId.Username = userName;
            projectCloudId.Password = password;
            projectCloudId.ProjectName = projectName;
            projectCloudId.ProjectId = new ProjectId(projectId);

            OpenStackIdentityProvider idProvider = new OpenStackIdentityProvider(baseUrl, projectCloudId);
            UserAccess userAccess = idProvider.Authenticate(projectCloudId);
            IEnumerable<ExtendedEndpoint> eps = idProvider.ListEndpoints(userAccess.Token.Id);

            string reg = idProvider.DefaultRegion; // This is null

            ServiceCatalog[] scs = userAccess.ServiceCatalog;

            // Get the list of regions
            regionList = new List<string>();
            foreach (ServiceCatalog sc in scs)
            {
                foreach (Endpoint ep in sc.Endpoints)
                {
                    regionList.Add(ep.Region); // This is 'regionOne' in every case
                }
            }

            // Try stuff...
            foreach(string region in regionList.Distinct())
            {
                // Get a list of containers
                CloudFilesProvider cfp = new CloudFilesProvider(projectCloudId, idProvider);
                // THIS LINE FAILS
                IEnumerable<Container> listOfContainers = cfp.ListContainers(region: region);
                foreach (Container ctnr in listOfContainers)
                {
                    Console.WriteLine("Container: {0}", ctnr.Name);
                }

                CloudNetworksProvider cnp = new CloudNetworksProvider(identity: null, identityProvider: idProvider);
                IEnumerable<CloudNetwork> networks = cnp.ListNetworks(identity: null, region: region);
                foreach (CloudNetwork network in networks)
                {
                    Console.WriteLine("Network[{0}] name: {1}", networkCount, network.Label);
                    Console.WriteLine("Network[{0}] Id: {1}", networkCount, network.Id);
                    ++networkCount;
                }

                Console.WriteLine("{0} networks listed.", networkCount);
            }
        }
        catch(Exception ex)
        {
            throw;
        }
    }

コードは ListContainers(region: region) の呼び出しでエラーで失敗します...「ユーザーは要求されたサービスまたはリージョンにアクセスできません」ここで、リージョンを指定しないかのように、エラーは単に「リージョンなし」ですが提供されましたが、サービスは地域に依存しないエンドポイントを提供しておらず、ユーザーのアカウントにデフォルトの地域が設定されていません」

現時点では内部ネットワークにのみアクセスしているため、リージョンはまだ重要ではありません...

また、電話をかけるときの注意点は...

CloudNetwork detail = cnp.ShowNetwork(networkGuid, "regionOne");

私が見ることができるネットワークの 'The item was not found or does not exist.' というエラーが返されます。

ヘルプとアドバイスをいただければ幸いです。

4

1 に答える 1

0

Openstack.Net SDK の機能をかなり簡単に拡張することができました。以下のコードは、テナント/プロジェクト操作のためのさまざまな機能を含むように拡張しています...

最初に、Web サービスとの間でデータをやり取りするために使用される NewTenant コンテナーを作成します。他のものと同じ名前空間に配置しました...

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;
        }
    }
}

これで、データを投稿するための新しい Request クラスを作成できます...

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;
        }
    }
}

次に、データの取得に役立つリクエストの Response オブジェクトを作成します

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; }
    }
}

これで、必要なテナント/プロジェクト操作のための追加機能を備えた OpenStackIdentityProvider から継承するクラスを作成できます...

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;
        }
    }
}

この機能は近日中に GitHub 版に登場すると思いますが、そうでない場合でも役に立つことを願っています。

于 2014-06-27T13:28:24.070 に答える