SoftLayer object storage is based on the OpenStack Swift object storage.
SoftLayer provides an SDK for storing its objects in Python, Ruby, Java and PHP, but not in .NET. Searching the .NET SDK for OpenStack, I came across OpenStack.NET .
Based on this question, OpenStack.NET is intended to be used with Rackspace by default, but can be made to work with other OpenStack providers using CloudIdentityWithProject
and OpenStackIdentityProvider
.
SoftLayer provides the following information to connect to their object store:
Authentication Endpoint
Public: https://mel01.objectstorage.softlayer.net/auth/v1.0/
Private: https://mel01.objectstorage.service.networklayer.com/auth/v1.0/
Username:
SLOS123456-1:email@example.com
API Key (Password):
1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
, CloudIdentityWithProject
OpenStackIdentityProvider
, //uri :
var cloudIdentity = new CloudIdentityWithProject()
{
ProjectName = "SLOS123456-1",
Username = "email@example.com",
Password = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
};
var identityProvider = new OpenStackIdentityProvider(
new Uri("https://mel01.objectstorage.softlayer.net/auth/v1.0/"),
cloudIdentity);
var token = identityProvider.GetToken(null);
:
Unable to authenticate user and retrieve authorized service endpoints
SoftLayer OpenStack.NET, , SoftLayer V1 auth, OpenStack.NET V2 auth.
SoftLayer SwiftStack, V1 auth /auth/v1.0/
(, , SoftLayer), X-Auth-User
X-Auth-Key
, , :
X-Auth-Token-Expires = 83436
X-Auth-Token = AUTH_tk1234567890abcdef1234567890abcdef
X-Storage-Token = AUTH_tk1234567890abcdef1234567890abcdef
X-Storage-Url = https://mel01.objectstorage.softlayer.net/v1/AUTH_12345678-1234-1234-1234-1234567890ab
X-Trans-Id = txbc1234567890abcdef123-1234567890
Connection = keep-alive
Content-Length = 1300
Content-Type = text/html; charset=UTF-8
Date = Wed, 14 Oct 2015 01:19:45 GMT
V2 auth ( API V2.0) /v2.0/tokens
, JSON body.
OpenStackIdentityProvider
OpenStack.NET, SoftLayerOpenStackIdentityProvider
:
using JSIStudios.SimpleRESTServices.Client;
using net.openstack.Core.Domain;
using net.openstack.Providers.Rackspace;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenStack.Authentication;
using System;
using System.Linq;
using System.Collections.Generic;
namespace OpenStackTest1
{
public class SoftLayerOpenStackIdentityProvider : CloudIdentityProvider
{
public SoftLayerOpenStackIdentityProvider(
Uri urlBase, CloudIdentity defaultIdentity)
: base(defaultIdentity, null, null, urlBase)
{
if (urlBase == null)
throw new ArgumentNullException("urlBase");
}
public override UserAccess GetUserAccess(
CloudIdentity identity, bool forceCacheRefresh = false)
{
identity = identity ?? DefaultIdentity;
Func<UserAccess> refreshCallback =
() =>
{
Dictionary<string, string> headers =
new Dictionary<string, string>();
headers["X-Auth-User"] = identity.Username;
headers["X-Auth-Key"] = identity.APIKey;
JObject requestBody = null;
var response = ExecuteRESTRequest<JObject>(
identity,
UrlBase,
HttpMethod.GET,
requestBody,
headers: headers,
isTokenRequest: true);
if (response == null || response.Data == null)
return null;
string authToken = response.Headers.Single(
h => h.Key == "X-Auth-Token").Value;
string storageUrl = response.Headers.Single(
h => h.Key == "X-Storage-Url").Value;
string tokenExpires = response.Headers.Single(
h => h.Key == "X-Auth-Token-Expires").Value;
int tokenExpiresSeconds = Int32.Parse(tokenExpires);
DateTimeOffset tokenExpiresDate =
DateTimeOffset.UtcNow.AddSeconds(tokenExpiresSeconds);
UserAccess access = JsonConvert.DeserializeObject<UserAccess>(
String.Format(
"{{ " +
" token: {{ id: '{0}', expires: '{1}' }}, " +
" serviceCatalog: " +
" [ " +
" {{ " +
" endpoints: [ {{ publicUrl: '{2}' }} ], " +
" type: 'object-store', " +
" name: 'swift' " +
" }} " +
" ], " +
" user: {{ }} " +
"}}",
authToken,
tokenExpiresDate,
storageUrl));
if (access == null || access.Token == null)
return null;
return access;
};
string key = string.Format("{0}:{1}", UrlBase, identity.Username);
var userAccess = TokenCache.Get(key, refreshCallback, forceCacheRefresh);
return userAccess;
}
protected override string LookupServiceTypeKey(IServiceType serviceType)
{
return serviceType.Type;
}
}
}
UserAccess
(, IdentityToken
Endpoint
) ( ), UserAccess
JSON , API V2.
, .. :
var cloudIdentity = new CloudIdentity()
{
Username = "SLOS123456-1:email@example.com",
APIKey = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
};
var identityProvider = new SoftLayerOpenStackIdentityProvider(
new Uri("https://mel01.objectstorage.softlayer.net/auth/v1.0/"),
cloudIdentity);
var token = identityProvider.GetToken(null);
.. :
var cloudFilesProvider = new CloudFilesProvider(identityProvider);
var containers = cloudFilesProvider.ListContainers();
var stream = new MemoryStream();
cloudFilesProvider.GetObject("testcontainer", "testfile.dat", stream);
SoftLayer .NET?
OpenStack SDK .NET ( OpenStack.NET), V2 auth.