Skip to content

Commit 751bd64

Browse files
committed
Add support and documentation for authenticating with the HP public cloud
1 parent 6976124 commit 751bd64

9 files changed

Lines changed: 345 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<topic id="182a1c50-9b73-4d72-abe3-b3578caedfa6" revisionNumber="1">
3+
<developerConceptualDocument
4+
xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5"
5+
xmlns:xlink="http://www.w3.org/1999/xlink">
6+
7+
<summary>
8+
<para>
9+
This page describes the process for authenticating against the HP Public Cloud.
10+
</para>
11+
</summary>
12+
13+
<introduction>
14+
<para></para>
15+
</introduction>
16+
17+
<section address="UsageNotes">
18+
<title>Usage Notes</title>
19+
<content>
20+
<para>
21+
Client authentication against the HP Cloud Identity Service requires the
22+
following.
23+
</para>
24+
<list class="ordered">
25+
<listItem>
26+
<para>
27+
Create an instance of <codeEntityReference>T:net.openstack.Core.Domain.CloudIdentityWithProject</codeEntityReference>
28+
and initialize its properties with the desired authentication credentials. The
29+
<codeEntityReference>T:net.openstack.Core.Domain.CloudIdentityWithProject</codeEntityReference>
30+
credentials class allows the <codeInline>tenantName</codeInline> and <codeInline>tenantId</codeInline>
31+
properties described in the HP documentation on <externalLink>
32+
<linkText>Scoped Tokens</linkText>
33+
<linkUri>http://docs.hpcloud.com/api/identity/#scoped-tokens</linkUri>
34+
</externalLink> to be defined.
35+
</para>
36+
<list class="bullet">
37+
<listItem>
38+
<para>
39+
To authenticate using access key credentials, specify the access key in the
40+
<codeEntityReference>P:net.openstack.Core.Domain.CloudIdentity.APIKey</codeEntityReference>
41+
property and the secret key in the
42+
<codeEntityReference>P:net.openstack.Core.Domain.CloudIdentity.Password</codeEntityReference>
43+
property.
44+
</para>
45+
</listItem>
46+
<listItem>
47+
<para>
48+
To authenticate using a username and password, set the
49+
<codeEntityReference>P:net.openstack.Core.Domain.CloudIdentity.Username</codeEntityReference>
50+
and <codeEntityReference>P:net.openstack.Core.Domain.CloudIdentity.Password</codeEntityReference>
51+
properties, leaving
52+
<codeEntityReference>P:net.openstack.Core.Domain.CloudIdentity.APIKey</codeEntityReference> unset.
53+
</para>
54+
</listItem>
55+
</list>
56+
</listItem>
57+
<listItem>
58+
<para>
59+
Create an instance of <codeEntityReference>T:net.openstack.Providers.Hp.HpIdentityProvider</codeEntityReference>,
60+
and pass the previously created credentials to the constructor.
61+
</para>
62+
</listItem>
63+
<listItem>
64+
<para>
65+
When creating a service provider instance, such as <codeEntityReference>T:net.openstack.Providers.Rackspace.CloudFilesProvider</codeEntityReference>,
66+
pass <markup>
67+
<span class="input">null</span>
68+
</markup> for the <codeEntityReference>T:net.openstack.Core.Domain.CloudIdentity</codeEntityReference>
69+
parameter and the identity provider from the previous step as the
70+
<codeEntityReference>T:net.openstack.Core.Providers.IIdentityProvider</codeEntityReference>
71+
parameter.
72+
</para>
73+
</listItem>
74+
</list>
75+
</content>
76+
</section>
77+
78+
<section address="Limitations">
79+
<title>Limitations</title>
80+
<content>
81+
<para>
82+
The <codeEntityReference>T:net.openstack.Providers.Hp.HpIdentityProvider</codeEntityReference> implementation
83+
does not support all API operations implemented by the HP Cloud Identity Service. In addition, the current
84+
implementation of this provider uses Identity Service v2 for authentication.
85+
</para>
86+
</content>
87+
</section>
88+
89+
<relatedTopics>
90+
<codeEntityReference>T:net.openstack.Core.Domain.CloudIdentityWithProject</codeEntityReference>
91+
<codeEntityReference>T:net.openstack.Providers.Hp.HpIdentityProvider</codeEntityReference>
92+
</relatedTopics>
93+
</developerConceptualDocument>
94+
</topic>

src/Documentation/Documentation.v3.5.shfbproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
<ItemGroup>
134134
<None Include="Content\AsynchronousServices.aml" />
135135
<None Include="Content\Authentication\Authentication.aml" />
136+
<None Include="Content\Authentication\HPAuthentication.aml" />
136137
<None Include="Content\Authentication\OpenStackAuthentication.aml" />
137138
<None Include="Content\Authentication\RackspaceAuthentication.aml" />
138139
<None Include="Content\License.aml" />

src/Documentation/Documentation.v4.0.shfbproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
<ItemGroup>
141141
<None Include="Content\AsynchronousServices.aml" />
142142
<None Include="Content\Authentication\Authentication.aml" />
143+
<None Include="Content\Authentication\HPAuthentication.aml" />
143144
<None Include="Content\Authentication\OpenStackAuthentication.aml" />
144145
<None Include="Content\Authentication\RackspaceAuthentication.aml" />
145146
<None Include="Content\License.aml" />

src/Documentation/OpenStackSDK.content

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Topic id="32cc6156-3b31-4450-b209-b55fcfc0a210" visible="True" title="Asynchronous Services" />
2020
<Topic id="92e2ae00-a53d-4efb-925f-2772495e9b6d" visible="True" isExpanded="true" title="Authentication">
2121
<Topic id="1bb35d97-0c79-4e98-a2ae-6c1eef098ba7" visible="True" title="OpenStack Authentication" />
22+
<Topic id="182a1c50-9b73-4d72-abe3-b3578caedfa6" visible="True" title="HP Authentication" />
2223
<Topic id="9135e7f8-b287-44ca-9faf-802a50dbad1a" visible="True" title="Rackspace Authentication" />
2324
</Topic>
2425
</Topics>
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
namespace net.openstack.Providers.Hp
2+
{
3+
using System;
4+
using net.openstack.Core.Caching;
5+
using net.openstack.Core.Domain;
6+
using Newtonsoft.Json.Linq;
7+
using CloudIdentityProvider = net.openstack.Providers.Rackspace.CloudIdentityProvider;
8+
using HttpMethod = JSIStudios.SimpleRESTServices.Client.HttpMethod;
9+
using IIdentityProvider = net.openstack.Core.Providers.IIdentityProvider;
10+
using IRestService = JSIStudios.SimpleRESTServices.Client.IRestService;
11+
using JsonRestServices = JSIStudios.SimpleRESTServices.Client.Json.JsonRestServices;
12+
13+
/// <summary>
14+
/// Provides an implementation of <see cref="IIdentityProvider"/> for operating with
15+
/// HP's Cloud Identity product. This provider supports authentication using a username/password
16+
/// combination or an access key/secret key combinatiton, and supports scoped tokens
17+
/// when credentials are represented with <see cref="CloudIdentityWithProject"/>.
18+
/// </summary>
19+
/// <seealso href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/">OpenStack Identity Service API v2.0 Reference</seealso>
20+
/// <seealso href="http://docs.hpcloud.com/api/identity/">HP Cloud v12.12 Identity Services API</seealso>
21+
/// <threadsafety static="true" instance="false"/>
22+
/// <preliminary/>
23+
public class HpIdentityProvider : CloudIdentityProvider
24+
{
25+
/// <summary>
26+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
27+
/// with no default identity, the <see cref="PredefinedHpIdentityEndpoints.Default"/> base URL, and the default REST service
28+
/// implementation and token cache.
29+
/// </summary>
30+
public HpIdentityProvider()
31+
: this(PredefinedHpIdentityEndpoints.Default, null, null, null)
32+
{
33+
}
34+
35+
/// <summary>
36+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
37+
/// with the specified default identity, the <see cref="PredefinedHpIdentityEndpoints.Default"/> base URL, and the default REST service
38+
/// implementation and token cache.
39+
/// </summary>
40+
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
41+
public HpIdentityProvider(CloudIdentity defaultIdentity)
42+
: this(PredefinedHpIdentityEndpoints.Default, defaultIdentity, null, null)
43+
{
44+
}
45+
46+
/// <summary>
47+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
48+
/// with no default identity, the <see cref="PredefinedHpIdentityEndpoints.Default"/> base URL, and the default REST service
49+
/// implementation, and token cache.
50+
/// </summary>
51+
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
52+
/// <param name="tokenCache">The cache to use for caching user access tokens. If this value is <see langword="null"/>, the provider will use <see cref="UserAccessCache.Instance"/>.</param>
53+
public HpIdentityProvider(IRestService restService, ICache<UserAccess> tokenCache)
54+
: this(PredefinedHpIdentityEndpoints.Default, null, restService, tokenCache)
55+
{
56+
}
57+
58+
/// <summary>
59+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
60+
/// using the <see cref="PredefinedHpIdentityEndpoints.Default"/> base URL and provided values.
61+
/// </summary>
62+
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
63+
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
64+
/// <param name="tokenCache">The cache to use for caching user access tokens. If this value is <see langword="null"/>, the provider will use <see cref="UserAccessCache.Instance"/>.</param>
65+
public HpIdentityProvider(CloudIdentity defaultIdentity, IRestService restService, ICache<UserAccess> tokenCache)
66+
: this(PredefinedHpIdentityEndpoints.Default, defaultIdentity, restService, tokenCache)
67+
{
68+
}
69+
70+
/// <summary>
71+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
72+
/// with no default identity, the specified base URL, and the default REST service
73+
/// implementation and token cache.
74+
/// </summary>
75+
/// <param name="urlBase">The base URL for the cloud instance. Predefined URLs are available in <see cref="PredefinedHpIdentityEndpoints"/>.</param>
76+
/// <exception cref="ArgumentNullException">If <paramref name="urlBase"/> is <see langword="null"/>.</exception>
77+
public HpIdentityProvider(Uri urlBase)
78+
: this(urlBase, null, null, null)
79+
{
80+
}
81+
82+
/// <summary>
83+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
84+
/// with the specified default identity and base URL, and the default REST service
85+
/// implementation and token cache.
86+
/// </summary>
87+
/// <param name="urlBase">The base URL for the cloud instance. Predefined URLs are available in <see cref="PredefinedHpIdentityEndpoints"/>.</param>
88+
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
89+
/// <exception cref="ArgumentNullException">If <paramref name="urlBase"/> is <see langword="null"/>.</exception>
90+
public HpIdentityProvider(Uri urlBase, CloudIdentity defaultIdentity)
91+
: this(urlBase, defaultIdentity, null, null)
92+
{
93+
}
94+
95+
/// <summary>
96+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
97+
/// with no default identity, and the specified base URL, REST service
98+
/// implementation, and token cache.
99+
/// </summary>
100+
/// <param name="urlBase">The base URL for the cloud instance. Predefined URLs are available in <see cref="PredefinedHpIdentityEndpoints"/>.</param>
101+
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
102+
/// <param name="tokenCache">The cache to use for caching user access tokens. If this value is <see langword="null"/>, the provider will use <see cref="UserAccessCache.Instance"/>.</param>
103+
/// <exception cref="ArgumentNullException">If <paramref name="urlBase"/> is <see langword="null"/>.</exception>
104+
public HpIdentityProvider(Uri urlBase, IRestService restService, ICache<UserAccess> tokenCache)
105+
: this(urlBase, null, restService, tokenCache)
106+
{
107+
}
108+
109+
/// <summary>
110+
/// Initializes a new instance of the <see cref="HpIdentityProvider"/> class
111+
/// using the provided values.
112+
/// </summary>
113+
/// <param name="urlBase">The base URL for the cloud instance. Predefined URLs are available in <see cref="PredefinedHpIdentityEndpoints"/>.</param>
114+
/// <param name="defaultIdentity">The default identity to use for calls that do not explicitly specify an identity. If this value is <see langword="null"/>, no default identity is available so all calls must specify an explicit identity.</param>
115+
/// <param name="restService">The implementation of <see cref="IRestService"/> to use for executing REST requests. If this value is <see langword="null"/>, the provider will use a new instance of <see cref="JsonRestServices"/>.</param>
116+
/// <param name="tokenCache">The cache to use for caching user access tokens. If this value is <see langword="null"/>, the provider will use <see cref="UserAccessCache.Instance"/>.</param>
117+
/// <exception cref="ArgumentNullException">If <paramref name="urlBase"/> is <see langword="null"/>.</exception>
118+
public HpIdentityProvider(Uri urlBase, CloudIdentity defaultIdentity, IRestService restService, ICache<UserAccess> tokenCache)
119+
: base(defaultIdentity, restService, tokenCache, urlBase)
120+
{
121+
if (urlBase == null)
122+
throw new ArgumentNullException("urlBase");
123+
}
124+
125+
/// <inheritdoc/>
126+
public override UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false)
127+
{
128+
if (identity == null)
129+
throw new ArgumentNullException("identity");
130+
131+
CloudIdentityWithProject identityWithProject = identity as CloudIdentityWithProject;
132+
if (identityWithProject == null)
133+
{
134+
if (identity.GetType() != typeof(CloudIdentity))
135+
throw new NotSupportedException(string.Format("{0} does not support credentials of type {1}", GetType().Name, identity.GetType().Name));
136+
}
137+
138+
Func<UserAccess> refreshCallback =
139+
() =>
140+
{
141+
JObject credentialsObject;
142+
if (!string.IsNullOrEmpty(identity.APIKey))
143+
{
144+
credentialsObject = new JObject(
145+
new JProperty("apiAccessKeyCredentials", new JObject(
146+
new JProperty("accessKey", identity.APIKey),
147+
new JProperty("secretKey", identity.Password))));
148+
}
149+
else
150+
{
151+
credentialsObject = new JObject(
152+
new JProperty("passwordCredentials", new JObject(
153+
new JProperty("username", identity.Username),
154+
new JProperty("password", identity.Password))));
155+
}
156+
157+
JObject authObject = new JObject(credentialsObject);
158+
if (identityWithProject != null && identityWithProject.ProjectId != null)
159+
authObject.Add("tenantId", JToken.FromObject(identityWithProject.ProjectId));
160+
if (identityWithProject != null && !string.IsNullOrEmpty(identityWithProject.ProjectName))
161+
authObject.Add("tenantName", JToken.FromObject(identityWithProject.ProjectName));
162+
163+
JObject requestBody = new JObject(
164+
new JProperty("auth", authObject));
165+
166+
var response = ExecuteRESTRequest<JObject>(identity, new Uri(UrlBase, "/v2.0/tokens"), HttpMethod.POST, requestBody, isTokenRequest: true);
167+
if (response == null || response.Data == null)
168+
return null;
169+
170+
JToken userAccessObject = response.Data["access"];
171+
if (userAccessObject == null)
172+
return null;
173+
174+
UserAccess access = userAccessObject.ToObject<UserAccess>();
175+
if (access == null || access.Token == null)
176+
return null;
177+
178+
return access;
179+
};
180+
string key = string.Format("{0}:{1}/{2}/{3}/{4}", UrlBase, identityWithProject != null ? identityWithProject.ProjectId : null, identity.Username, identity.APIKey, identity.Password);
181+
var userAccess = TokenCache.Get(key, refreshCallback, forceCacheRefresh);
182+
183+
return userAccess;
184+
}
185+
}
186+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace net.openstack.Providers.Hp
2+
{
3+
using System.Runtime.CompilerServices;
4+
5+
/// <summary>
6+
/// The <see cref="net.openstack.Providers.Hp"/> namespaces provide an
7+
/// implementation of the core OpenStack interfaces for accessing HP cloud
8+
/// products and services, as well as additional HP-specific functionality.
9+
/// </summary>
10+
[CompilerGenerated]
11+
internal class NamespaceDoc
12+
{
13+
}
14+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
namespace net.openstack.Providers.Hp
2+
{
3+
using System;
4+
5+
/// <summary>
6+
/// Provides endpoints for the HP Cloud Identity Service.
7+
/// </summary>
8+
/// <remarks>
9+
/// As HP accounts are global, any region can be used for conducting identity
10+
/// operations. Choose the region closest to you for improved performance, or
11+
/// use <see cref="Default"/> for general API operations.
12+
/// </remarks>
13+
/// <threadsafety static="true" instance="false"/>
14+
/// <preliminary/>
15+
public static class PredefinedHpIdentityEndpoints
16+
{
17+
/// <summary>
18+
/// Gets the HP Cloud Identity Service endpoint for the US-West region.
19+
/// </summary>
20+
/// <remarks>
21+
/// As HP accounts are global, any region can be used for conducting identity
22+
/// operations. Choose the region closest to you for improved performance, or
23+
/// use <see cref="Default"/> for general API operations.
24+
/// </remarks>
25+
public static readonly Uri UsWest = new Uri("https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0/");
26+
27+
/// <summary>
28+
/// Gets the HP Cloud Identity Service endpoint for the US-East region.
29+
/// </summary>
30+
/// <remarks>
31+
/// As HP accounts are global, any region can be used for conducting identity
32+
/// operations. Choose the region closest to you for improved performance, or
33+
/// use <see cref="Default"/> for general API operations.
34+
/// </remarks>
35+
public static readonly Uri UsEast = new Uri("https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/");
36+
37+
/// <summary>
38+
/// Gets the default endpoint for the HP Cloud Identity Service.
39+
/// </summary>
40+
public static readonly Uri Default = UsEast;
41+
}
42+
}

0 commit comments

Comments
 (0)