Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified lib/SimpleRestServices.dll
Binary file not shown.
Binary file modified lib/SimpleRestServices.pdb
Binary file not shown.
42 changes: 42 additions & 0 deletions src/corelib/Core/Domain/ServerState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace net.openstack.Core.Domain
{
public class ServerState
{
public static string ACTIVE { get { return "ACTIVE"; } }

public static string BUILD { get { return "BUILD"; } }

public static string DELETED { get { return "DELETED"; } }

public static string ERROR { get { return "ERROR"; } }

public static string HARD_REBOOT { get { return "HARD_REBOOT"; } }

public static string MIGRATING { get { return "MIGRATING"; } }

public static string PASSWORD { get { return "PASSWORD"; } }

public static string REBOOT { get { return "REBOOT"; } }

public static string REBUILD { get { return "REBUILD"; } }

public static string RESCUE { get { return "RESCUE"; } }

public static string RESIZE { get { return "RESIZE"; } }

public static string REVERT_RESIZE { get { return "REVERT_RESIZE"; } }

public static string SUSPENDED { get { return "SUSPENDED"; } }

public static string UNKNOWN { get { return "UNKNOWN"; } }

public static string VERIFY_RESIZE { get { return "VERIFY_RESIZE"; } }
}

public class ImageState : ServerState{}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace net.openstack.Core.Exceptions.Response
{
class MethodNotImplementedException : ResponseException
{
public MethodNotImplementedException(SimpleRestServices.Client.Response response) : base("The requested method is not implemented at the service.", response) { }

public MethodNotImplementedException(string message, SimpleRestServices.Client.Response response) : base(message, response) {}
}
}
1 change: 1 addition & 0 deletions src/corelib/Core/Exceptions/Response/ResponseException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace net.openstack.Core.Exceptions.Response
{
[Serializable]
public class ResponseException : Exception
{
public SimpleRestServices.Client.Response Response { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;

namespace net.openstack.Core.Exceptions.Response
{
[Serializable]
public class UserNotAuthorizedException : ResponseException
{
public UserNotAuthorizedException(SimpleRestServices.Client.Response response) : base("Unable to authenticate user and retrieve authorized service endpoints", response){}
Expand Down
7 changes: 7 additions & 0 deletions src/corelib/Core/IComputeProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public interface IComputeProvider
string GetImageMetadataItem(CloudIdentity identity, string cloudServerId, string key, string region = null);
bool SetImageMetadataItem(CloudIdentity identity, string cloudServerId, string key, string value, string region = null);
bool DeleteImageMetadataItem(CloudIdentity identity, string cloudServerId, string key, string region = null);

ServerDetails WaitForServerState(CloudIdentity identity, string cloudServerId, string expectedState, string[] errorStates, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
ServerDetails WaitForServerActive(CloudIdentity identity, string cloudServerId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
ServerDetails WaitForServerDeleted(CloudIdentity identity, string cloudServerId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
ServerImageDetails WaitForImageState(CloudIdentity identity, string imageId, string expectedState, string[] errorStates, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
ServerImageDetails WaitForImageActive(CloudIdentity identity, string imageId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
ServerImageDetails WaitForImageDeleted(CloudIdentity identity, string imageId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400);
}
}

1 change: 1 addition & 0 deletions src/corelib/Core/IIdentityProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public interface IIdentityProvider
UserCredential[] ListUserCredentials(CloudIdentity identity, string userId);

Tenant[] ListTenants(CloudIdentity identity);
UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false);
}
}
67 changes: 67 additions & 0 deletions src/corelib/Providers/Rackspace/ComputeProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using SimpleRestServices.Client;
using SimpleRestServices.Client.Json;
using net.openstack.Core;
Expand Down Expand Up @@ -116,6 +117,34 @@ public bool DeleteServer(CloudIdentity identity, string cloudServerId, string re
return true;
}

public ServerDetails WaitForServerState(CloudIdentity identity, string cloudServerId, string expectedState, string[] errorStates, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
var serverDetails = GetDetails(identity, cloudServerId, region);

int count = 0;
while (!serverDetails.Status.Equals(expectedState) && !errorStates.Contains(serverDetails.Status) && count < refreshCount)
{
Thread.Sleep(refreshDelayInMS);
serverDetails = GetDetails(identity, cloudServerId, region);
count++;
}

if (errorStates.Contains(serverDetails.Status))
throw new ServerEnteredErrorStateException(serverDetails.Status);

return serverDetails;
}

public ServerDetails WaitForServerActive(CloudIdentity identity, string cloudServerId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
return WaitForServerState(identity, cloudServerId, ServerState.ACTIVE, new [] {ServerState.ERROR, ServerState.UNKNOWN, ServerState.SUSPENDED}, region, refreshCount, refreshDelayInMS);
}

public ServerDetails WaitForServerDeleted(CloudIdentity identity, string cloudServerId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
return WaitForServerState(identity, cloudServerId, ServerState.DELETED, new[] { ServerState.ERROR, ServerState.UNKNOWN, ServerState.SUSPENDED }, region, refreshCount, refreshDelayInMS);
}

#endregion

#region Server Addresses
Expand Down Expand Up @@ -394,6 +423,34 @@ public bool DeleteImage(CloudIdentity identity, string imageId, string region =
return true;
}

public ServerImageDetails WaitForImageState(CloudIdentity identity, string imageId, string expectedState, string[] errorStates, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
var details = GetImage(identity, imageId, region);

int count = 0;
while (!details.Status.Equals(expectedState) && !errorStates.Contains(details.Status) && count < refreshCount)
{
Thread.Sleep(refreshDelayInMS);
details = GetImage(identity, imageId, region);
count++;
}

if (errorStates.Contains(details.Status))
throw new ServerEnteredErrorStateException(details.Status);

return details;
}

public ServerImageDetails WaitForImageActive(CloudIdentity identity, string imageId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
return WaitForImageState(identity, imageId, ImageState.ACTIVE, new[] { ImageState.ERROR, ImageState.UNKNOWN, ImageState.SUSPENDED }, region, refreshCount, refreshDelayInMS);
}

public ServerImageDetails WaitForImageDeleted(CloudIdentity identity, string imageId, string region = null, int refreshCount = 600, int refreshDelayInMS = 2400)
{
return WaitForImageState(identity, imageId, ImageState.DELETED, new[] { ImageState.ERROR, ImageState.UNKNOWN, ImageState.SUSPENDED }, region, refreshCount, refreshDelayInMS);
}

#endregion

#region Server Metadata
Expand Down Expand Up @@ -557,4 +614,14 @@ protected string GetServiceEndpoint(CloudIdentity identity, string region = null

#endregion
}

public class ServerEnteredErrorStateException : Exception
{
public string Status { get; private set; }

public ServerEnteredErrorStateException(string status) : base(string.Format("The server entered an error state: '{0}'", status))
{
Status = status;
}
}
}
53 changes: 38 additions & 15 deletions src/corelib/Providers/Rackspace/GeographicalIdentityProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,22 @@ public bool SetUserPassword(CloudIdentity identity, string userId, string passwo
{
var user = GetUser(identity, userId);

return SetUserPassword(identity, user, password);
}

public bool SetUserPassword(CloudIdentity identity, User user, string password)
{
return SetUserPassword(identity, user.Id, user.Username, password);
}

public bool SetUserPassword(CloudIdentity identity, string userId, string username, string password)
{
var urlPath = string.Format("v2.0/users/{0}/OS-KSADM/credentials", userId);
var request = new SetPasswordRequest
{
PasswordCredencial =
new PasswordCredencial {Username = user.Username, Password = password}
};
{
PasswordCredencial =
new PasswordCredencial { Username = username, Password = password }
};
var response = ExecuteRESTRequest<PasswordCredencialResponse>(identity, urlPath, HttpMethod.POST, request);

if (response == null || response.StatusCode != 201 || response.Data == null)
Expand All @@ -128,8 +138,18 @@ public UserCredential UpdateUserCredentials(CloudIdentity identity, string userI
{
var user = GetUser(identity, userId);

return UpdateUserCredentials(identity, user, apiKey);
}

public UserCredential UpdateUserCredentials(CloudIdentity identity, User user, string apiKey)
{
return UpdateUserCredentials(identity, user.Id, user.Username, apiKey);
}

public UserCredential UpdateUserCredentials(CloudIdentity identity, string userId, string username, string apiKey)
{
var urlPath = string.Format("v2.0/users/{0}/OS-KSADM/credentials/RAX-KSKEY:apiKeyCredentials", userId);
var request = new UpdateUserCredencialRequest { UserCredential = new UserCredential { Username = user.Username, APIKey = apiKey } };
var request = new UpdateUserCredencialRequest { UserCredential = new UserCredential { Username = username, APIKey = apiKey } };
var response = ExecuteRESTRequest<UserCredentialResponse>(identity, urlPath, HttpMethod.POST, request);

if (response == null || response.Data == null)
Expand Down Expand Up @@ -280,24 +300,27 @@ public IdentityToken GetTokenInfo(CloudIdentity identity, bool forceCacheRefresh

public UserAccess Authenticate(CloudIdentity identity)
{
var auth = AuthRequest.FromCloudIdentity(identity);
var response = ExecuteRESTRequest<AuthenticationResponse>(identity, "/v2.0/tokens", HttpMethod.POST, auth, isTokenRequest: true);


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

return response.Data.UserAccess;
return GetUserAccess(identity, true);
}

private UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false)
public UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false)
{
var rackspaceCloudIdentity = identity as RackspaceCloudIdentity;

if (rackspaceCloudIdentity == null)
throw new InvalidCloudIdentityException(string.Format("Invalid Identity object. Rackspace Identity service requires an instance of type: {0}", typeof(RackspaceCloudIdentity)));

var userAccess = _userAccessCache.Get(string.Format("{0}/{1}", rackspaceCloudIdentity.CloudInstance, rackspaceCloudIdentity.Username), () => Authenticate(rackspaceCloudIdentity), forceCacheRefresh);
var userAccess = _userAccessCache.Get(string.Format("{0}/{1}", rackspaceCloudIdentity.CloudInstance, rackspaceCloudIdentity.Username), () =>
{
var auth = AuthRequest.FromCloudIdentity(identity);
var response = ExecuteRESTRequest<AuthenticationResponse>(identity, "/v2.0/tokens", HttpMethod.POST, auth, isTokenRequest: true);


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

return response.Data.UserAccess;
}, forceCacheRefresh);

return userAccess;
}
Expand Down
4 changes: 4 additions & 0 deletions src/corelib/Providers/Rackspace/IExtendedIdentityProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ public interface IExtendedIdentityProvider : IIdentityProvider
UserCredential UpdateUserCredentials(CloudIdentity identity, string userId, string apiKey);
bool DeleteUserCredentials(CloudIdentity identity, string userId);
bool SetUserPassword(CloudIdentity identity, string userId, string password);
bool SetUserPassword(CloudIdentity identity, User user, string password);
bool SetUserPassword(CloudIdentity identity, string userId, string username, string password);
UserCredential UpdateUserCredentials(CloudIdentity identity, User user, string apiKey);
UserCredential UpdateUserCredentials(CloudIdentity identity, string userId, string username, string apiKey);
}
}
30 changes: 30 additions & 0 deletions src/corelib/Providers/Rackspace/IdentityProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ public bool SetUserPassword(CloudIdentity identity, string userId, string passwo
return provider.SetUserPassword(identity, userId, password);
}

public bool SetUserPassword(CloudIdentity identity, User user, string password)
{
var provider = GetProvider(identity);
return provider.SetUserPassword(identity, user, password);
}

public bool SetUserPassword(CloudIdentity identity, string userId, string username, string password)
{
var provider = GetProvider(identity);
return provider.SetUserPassword(identity, userId, username, password);
}

public UserCredential UpdateUserCredentials(CloudIdentity identity, User user, string apiKey)
{
var provider = GetProvider(identity);
return provider.UpdateUserCredentials(identity, user, apiKey);
}

public UserCredential UpdateUserCredentials(CloudIdentity identity, string userId, string username, string apiKey)
{
var provider = GetProvider(identity);
return provider.UpdateUserCredentials(identity, userId, username, apiKey);
}

public UserCredential[] ListUserCredentials(CloudIdentity identity, string userId)
{
var provider = GetProvider(identity);
Expand All @@ -115,6 +139,12 @@ public Tenant[] ListTenants(CloudIdentity identity)
return provider.ListTenants(identity);
}

public UserAccess GetUserAccess(CloudIdentity identity, bool forceCacheRefresh = false)
{
var provider = GetProvider(identity);
return provider.GetUserAccess(identity, forceCacheRefresh);
}

public string GetToken(CloudIdentity identity, bool forceCacheRefresh = false)
{
var provider = GetProvider(identity);
Expand Down
4 changes: 3 additions & 1 deletion src/corelib/Providers/Rackspace/ProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ internal JsonRequestSettings BuildDefaultRequestSettings(IEnumerable<int> non200

protected virtual string GetServiceEndpoint(CloudIdentity identity, string serviceName, string region = null)
{
var userAccess = _identityProvider.Authenticate(identity);
var userAccess = _identityProvider.GetUserAccess(identity);

if (userAccess == null || userAccess.ServiceCatalog == null)
throw new UserAuthenticationException("Unable to authenticate user and retrieve authorized service endpoints");
Expand Down Expand Up @@ -144,6 +144,8 @@ internal static void CheckResponse(Response response)
throw new ServiceLimitReachedException(response);
case 500:
throw new ServiceFaultException(response);
case 501:
throw new MethodNotImplementedException(response);
case 503:
throw new ServiceUnavailableException(response);
}
Expand Down
2 changes: 2 additions & 0 deletions src/corelib/corelib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@
<Compile Include="Core\Domain\Personality.cs" />
<Compile Include="Core\Domain\RebootType.cs" />
<Compile Include="Core\Domain\ServerAddresses.cs" />
<Compile Include="Core\Domain\ServerState.cs" />
<Compile Include="Core\Domain\Tenant.cs" />
<Compile Include="Core\Domain\UserCredential.cs" />
<Compile Include="Core\Exceptions\Response\BadServiceRequestException.cs" />
<Compile Include="Core\Exceptions\Response\ItemNotFoundException.cs" />
<Compile Include="Core\Exceptions\Response\MethodNotImplementedException.cs" />
<Compile Include="Core\Exceptions\Response\ServiceFaultException.cs" />
<Compile Include="Core\Exceptions\Response\ServiceLimitReachedException.cs" />
<Compile Include="Core\Exceptions\Response\ServiceUnavailableException.cs" />
Expand Down
Loading