2014-06-19 6 views
0

자체 하드웨어를 사용하여 모든 구성 요소와 함께 vanilla openstack을 설치했지만 지역 문제로 인해 ID 이외의 서비스에 액세스하는 데 문제가 있습니다. 우리가 만든 관리자 계정 및 관리자 테넌트 호출은 다음과 같이 사용되는 코드는Openstack.Net SDK가 지역별 서비스를 액세스 할 수 없습니다.

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 (지역 : 지역)에 대한 호출에 실패입니다 ... 오류가있는 ... '사용자는하지 않습니다 요청 된 서비스 또는 지역에 대한 액세스 권한이 있어야합니다. '내가 영역을 지정하지 않은 경우 오류가 단순히'지역이 제공되지 않았습니다. 서비스가 지역 독립적 종점을 제공하지 않으며 사용자의 기본 지역이 설정되지 않았습니다. 계정 '지역은 아직 우리에게 중요하지 않습니다, 그래서 우리는 지금 우리의 내부 네트워크에 액세스하는

... 또한

참고이다를 호출 ... 내가 반환 오류가 볼 수있는 네트워크의

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

할 때 그 '항목을 찾을 수 없거나 존재하지 않습니다.'

많은 도움과 조언을드립니다.

+0

Visual Studio에서 심볼 소스를 활성화하면 디버거의 ListContainers 코드로 들어갈 수 있습니다. http://www.symbolsource.org/Public/Home/VisualStudio 이것은보다 구체적인 원인을 추적하는 데 도움이 될 수 있습니다. –

+0

github에서 소스를 다운로드하여 연결했습니다. 지금 문제를 볼 수 있습니다. CloudNetworksProvider는 {0}/os-networksv2로 이동합니다. 표준 openstack이 {0}/os-network 일 필요가있어 'Item not found'예외가 발생합니다. CloudFilesProvider는 오해였습니다. Object Storage가 설치되지 않았기 때문에 '사용자에게는 액세스 권한이 없습니다.'라는 예외가있었습니다. 바닐라 OpenStack 버전의 클래스를 만들지 않고 {0}/os-networksv2를 얻는 방법에 대한 권장 사항은 무엇입니까? – Hoots

+0

Rackspace는 [Compute API Networks (os-networks) 확장]과 유사한 네트워킹 지원을 사용합니다 (http://docs.openstack.org/api/openstack-compute/2/content/ext-os-networks). html)하지만 다른 끝점을 사용합니다. openstack.net SDK의 v2.0 릴리스는 당신이 필요로하는 [OpenStack Networking API] (http://docs.openstack.org/api/openstack-network/2.0/content/)에 대한 지원을 추가합니다 다른 OpenStack 설치.이 주요 업데이트의 현재 상태는 다음 페이지를 참조하십시오. https://github.com/openstacknetsdk/openstack.net/wiki/V2.0 –

답변

0

나는 Openstack.Net SDK의 기능을 상당히 간단하게 확장 할 수있었습니다. 아래 코드는 임차인/프로젝트 조작을위한 다양한 함수를 포함하도록 확장합니다 ...

먼저 웹 서비스와 데이터를주고받는 데 사용할 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; 
     } 
    } 
} 

이제 우리는

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

지금 데이터를 검색하는 데 도움 요청에 대한 응답 객체를 생성 ... 데이터를 게시 새로운 요청 클래스를 만들 수 있습니다

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의 버전에 나타납니다 상상 그러나 그렇지 않다면 나는 그것이 유용하길 바란다.