一、openstack.net 介绍
- openstack.net有什么用?主要是为.net开发人员提供了一套对openstack平台操作的SDK,可以简单看成基于.Net平台的CLI工具,从而为.Net开发人员提供方便的二次开发云计算平台的功能。
当前openstack.net项目用c#实现,由Rackspace公司实现其业务基础上对外开源,项目地址:
https://github.com/openstacknetsdk/openstack.net
http://www.openstacknetsdk.org/
-
openstack.net简单结构
- Keystone相关:provider和Identity
provider就是您的帐户所在地。例如Rackspace、VMWare、Azure、Openstack等。显然,您不能使用Rackspace帐户在Azure创建(或“启动”)服务器。通过在提供商处对您的帐户进行身份验证,您可以获得身份,从而可以使用云对象。换言之,您的身份就是您在特定provider的Identity。
使用云对象时,可以通过以下两种方式之一使用Identity:
可以在每次方法调用中传递Identity对象,或者
可以在创建提供程序对象时指定标识对象,之后使用该提供程序对象的所有调用都将使用标识对象。
例如:
_cloudIdentity = new CloudIdentity(){Username = "username", APIKey = "api_key_goes_here"};
示例1
一旦Identity对象被创建,它就被用来创建Provider对象。Provider对象允许您执行云任务,如启动服务器、上载文件等。
下面的示例(示例2)使用Identity对象演示如何创建Provider对象。请注意,在实例化提供程序时包含Identity对象。这使得我们可以进行后续调用,而不需要每次都包含标识。
_provider = new CloudServersProvider(_cloudIdentity);
示例2
现在我们有了一个Provider对象,我们可以使用它来执行云任务(本文后面将详细介绍这些任务),比如启动服务器。
例如启动服务器实例。完全理解这个例子并不重要,只需要清楚地理解了这个原则:提供者是您完成大部分工作的地方。
NewServer newServer = _provider.CreateServer(serverName, imageId, flavorId);
- 实例servers相关
云计算的一个基本特性是能够在需求增加时启动额外的服务器,并在需求减少时进行缩减。
OpenStack允许您以编程方式启动服务器。一个软件开发人员可以在几分钟内编写几行代码,这是过去硬件技术人员和网络管理员需要几天时间才能完成的工作。
根据提供程序的不同,您可能有许多操作系统和虚拟机配置可供选择。此外,还可能提供某些软件。
利用openstack.net定义启动一个实例服务的典型代码如下,
定义:
public ServerCreateDefinition(string name, Identifier imageId, Identifier flavorId)
{
Name = name;
ImageId = imageId;
FlavorId = flavorId;
SecurityGroups = new List<SecurityGroupReference>();
Networks = new List<ServerNetworkDefinition>();
Metadata = new Dictionary<string, string>();
Personality = new List<Personality>();
BlockDeviceMapping = new List<ServerBlockDeviceMapping>();
}
创建:
public virtual async Task<T> CreateServerAsync<T>(object server, CancellationToken cancellationToken = default(CancellationToken))
where T : IServiceResource
{
return await BuildCreateServerRequest(server, cancellationToken)
.SendAsync()
.ReceiveJson<T>()
.PropogateOwner(this).ConfigureAwait(false);
}
二、使用
openstack.net开源项目内置sample,看一下其运行情况
创建server,创建snapshot
using System;
using System.Linq;
using System.Threading.Tasks;
using net.openstack.Core.Domain;
using net.openstack.Core.Providers;
using OpenStack.Compute.v2_1;
public class ComputeSample : ISample
{
public async Task Run(string identityEndpoint, string username, string password, string project, string region)
{
// Configure authentication
var user = new CloudIdentityWithProject
{
Username = username,
Password = password,
ProjectName = project
};
var identity = new OpenStackIdentityProvider(new Uri(identityEndpoint), user);
var compute = new ComputeService(identity, region);
Console.WriteLine("Looking up the tiny flavor...");
var flavors = await compute.ListFlavorsAsync();
var tinyFlavor = flavors.FirstOrDefault(x => x.Name.Contains("tiny"));
if (tinyFlavor == null) throw new Exception("Unable to find a flavor with the 'tiny' in the name!");
Console.WriteLine("Looking up the cirros image...");
var images = await compute.ListImagesAsync(new ImageListOptions { Name = "cirros" });
var cirrosImage = images.FirstOrDefault();
if (cirrosImage == null) throw new Exception("Unable to find an image named 'cirros'");
Console.WriteLine("Creating Sample server... ");
var serverDefinition = new ServerCreateDefinition("sample", cirrosImage.Id, tinyFlavor.Id);
//附上网络
var insideNetwork = new ServerNetworkDefinition
{
NetworkId = "8c7f834d-e552-4996-9810-e706b3e7a3a5"
};
serverDefinition.Networks.Add(insideNetwork);
var server = await compute.CreateServerAsync(serverDefinition);
Console.WriteLine("Waiting for the sample server to come online...");
await server.WaitUntilActiveAsync();
Console.WriteLine("Taking a snaphot of the sample server...");
var snapshot = await server.SnapshotAsync(new SnapshotServerRequest("sample-snapshot"));
await snapshot.WaitUntilActiveAsync();
Console.WriteLine();
Console.WriteLine("Sample Server Information:");
Console.WriteLine();
Console.WriteLine($"Server Id: {server.Id}");
Console.WriteLine($"Server Name: {server.Name}");
Console.WriteLine($"Server Status: {server.Status}");
Console.WriteLine($"Server Address: {server.IPv4Address}");
Console.WriteLine();
Console.WriteLine("Sample Snapshot Information:");
Console.WriteLine();
Console.WriteLine($"Image Id: {snapshot.Id}");
Console.WriteLine($"Image Name: {snapshot.Name}");
Console.WriteLine($"Image Status: {snapshot.Status}");
Console.WriteLine($"Image Type: {snapshot.Type}");
Console.WriteLine();
Console.WriteLine("Deleting Sample Server...");
await snapshot.DeleteAsync();
await server.DeleteAsync();
}
public void PrintTasks()
{
Console.WriteLine("This sample will perform the following tasks:");
Console.WriteLine("\t* Lookup a flavor with tiny in the name");
Console.WriteLine("\t* Lookup an image named cirros");
Console.WriteLine("\t* Create a server using cirros and the tiny flavor");
Console.WriteLine("\t* Snapshot the server");
Console.WriteLine("\t* Delete the snapshot and server");
}
}
运行结果:
openstack面板中可以看到同步的服务实例创建
创建网络和子网
using System;
using System.Linq;
using System.Threading.Tasks;
using net.openstack.Core.Domain;
using net.openstack.Core.Providers;
using OpenStack.Networking;
using OpenStack.Networking.v2;
public class NetworkingSample : ISample
{
public async Task Run(string identityEndpoint, string username, string password, string project, string region)
{
// Configure authentication
var user = new CloudIdentityWithProject
{
Username = username,
Password = password,
ProjectName = project
};
var identity = new OpenStackIdentityProvider(new Uri(identityEndpoint), user);
var networking = new NetworkingService(identity, region);
Console.WriteLine("Creating Sample Network... ");
var networkDefinition = new NetworkDefinition {Name = "Sample"};
var sampleNetwork = await networking.CreateNetworkAsync(networkDefinition);
Console.WriteLine("Adding a subnet to Sample Network...");
var subnetDefinition = new SubnetCreateDefinition(sampleNetwork.Id, IPVersion.IPv4, "192.0.2.0/24")
{
Name = "Sample"
};
var sampleSubnet = await networking.CreateSubnetAsync(subnetDefinition);
Console.WriteLine("Attaching a port to Sample Network...");
var portDefinition = new PortCreateDefinition(sampleNetwork.Id)
{
Name = "Sample"
};
var samplePort = await networking.CreatePortAsync(portDefinition);
Console.WriteLine("Listing Networks...");
var networks = await networking.ListNetworksAsync();
foreach (Network network in networks)
{
Console.WriteLine($"{network.Id}\t\t\t{network.Name}");
}
Console.WriteLine();
Console.WriteLine("Sample Network Information:");
Console.WriteLine();
Console.WriteLine($"Network Id: {sampleNetwork.Id}");
Console.WriteLine($"Network Name: {sampleNetwork.Name}");
Console.WriteLine($"Network Status: {sampleNetwork.Status}");
Console.WriteLine();
Console.WriteLine($"Subnet Id: {sampleSubnet.Id}");
Console.WriteLine($"Subnet Name: {sampleSubnet.Name}");
Console.WriteLine($"Subnet IPs: {sampleSubnet.AllocationPools.First().Start} - {sampleSubnet.AllocationPools.First().End}");
Console.WriteLine();
Console.WriteLine($"Port Id: {samplePort.Id}");
Console.WriteLine($"Port Name: {samplePort.Name}");
Console.WriteLine($"Port Address: {samplePort.MACAddress}");
Console.WriteLine($"Port Status: {samplePort.Status}");
Console.WriteLine();
Console.WriteLine("Deleting Sample Network...");
await networking.DeletePortAsync(samplePort.Id);
await networking.DeleteNetworkAsync(sampleNetwork.Id);
}
public void PrintTasks()
{
Console.WriteLine("This sample will perform the following tasks:");
Console.WriteLine("\t* Create a network");
Console.WriteLine("\t* Add a subnet to the network");
Console.WriteLine("\t* Attach a port to the network");
Console.WriteLine("\t* Delete the network");
}
}
运行结果:
openstack面板中sample网络已创建
三、参考文档
https://github.com/openstacknetsdk/openstack.net/wiki/Getting-Started-With-The-OpenStack-NET-SDK
http://www.openstacknetsdk.org/docs/html/e11545c6-88c9-4ff1-b0cf-abffd4bd3ff7.htm