yao 0.0.2.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +2 -0
- data/lib/yao/auth.rb +74 -0
- data/lib/yao/client.rb +70 -0
- data/lib/yao/config.rb +52 -0
- data/lib/yao/faraday_middlewares.rb +14 -0
- data/lib/yao/is_openstack_client.rb +14 -0
- data/lib/yao/resources/base.rb +69 -0
- data/lib/yao/resources/flavor.rb +21 -0
- data/lib/yao/resources/floating_ip.rb +9 -0
- data/lib/yao/resources/hypervisor.rb +20 -0
- data/lib/yao/resources/image.rb +28 -0
- data/lib/yao/resources/keypair.rb +13 -0
- data/lib/yao/resources/metadata_available.rb +50 -0
- data/lib/yao/resources/network.rb +14 -0
- data/lib/yao/resources/port.rb +24 -0
- data/lib/yao/resources/restfully_accessible.rb +91 -0
- data/lib/yao/resources/security_group.rb +40 -0
- data/lib/yao/resources/security_group_rule.rb +55 -0
- data/lib/yao/resources/server.rb +17 -0
- data/lib/yao/resources/subnet.rb +22 -0
- data/lib/yao/resources.rb +25 -0
- data/lib/yao/version.rb +3 -0
- data/lib/yao.rb +9 -0
- data/yao.gemspec +31 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 04c45b85c7164bc9cd7bac93189eec8c2aff4712
|
4
|
+
data.tar.gz: cb05d894031f89862beba5e27c372ba7ec09d8e3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4745f172f77fd7fa273f2253ab94394b6223d5d26fd0d10c42cd809bea46b05b3059cf9cb260acb8fdc7eb6cad0303aff87c68321ebbb15dda2a86b615a47ec
|
7
|
+
data.tar.gz: 415e8fcd67ca260f14ec1105d83197680c0c999a7d1c5f07ee2ea00263a0c99d9c5401aaddde7b7d77b7d99153d2c858914481f885d9ed98fb3ab0fa83b6b258
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Uchio, KONDO
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Yao
|
2
|
+
|
3
|
+
YAO is a Yet Another OpenStack API Wrapper that rocks!!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'yao'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install yao
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'yao'
|
25
|
+
|
26
|
+
Yao.configure do
|
27
|
+
auth_url "http://keystone.example.local:8080/v2.0/tokens"
|
28
|
+
tenant_name "fooproject"
|
29
|
+
username "udzura"
|
30
|
+
password "tonk0tsu-r@men"
|
31
|
+
end
|
32
|
+
|
33
|
+
Yao::Network.list # list up networks...
|
34
|
+
Yao::Server.list_detail # list up instances...
|
35
|
+
```
|
36
|
+
|
37
|
+
## Pro tips
|
38
|
+
|
39
|
+
You can use a prittier namespace:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# Instead of require-ing 'yao'
|
43
|
+
require 'yao/is_openstack_client'
|
44
|
+
|
45
|
+
OpenStack.configure do
|
46
|
+
auth_url "http://keystone.example.local:8080/v2.0/tokens"
|
47
|
+
tenant_name "fooproject"
|
48
|
+
username "udzura"
|
49
|
+
password "tonk0tsu-r@men"
|
50
|
+
end
|
51
|
+
|
52
|
+
OpenStack::Server.list_detail # And let's go on
|
53
|
+
```
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it ( https://github.com/udzura/yao/fork )
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/yao/auth.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'yao'
|
2
|
+
require 'json'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Yao::Auth
|
6
|
+
%i(tenant_name username password).each do |name|
|
7
|
+
Yao.config.param name, nil do |_|
|
8
|
+
Yao::Auth.try_new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def try_new
|
14
|
+
if Yao.config.tenant_name && Yao.config.username && Yao.config.password && Yao.default_client
|
15
|
+
Yao::Auth.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def new(
|
20
|
+
tenant_name: Yao.config.tenant_name,
|
21
|
+
username: Yao.config.username,
|
22
|
+
password: Yao.config.password
|
23
|
+
)
|
24
|
+
authinfo = {
|
25
|
+
auth: {
|
26
|
+
passwordCredentials: {
|
27
|
+
username: username, password: password
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
authinfo[:auth][:tenantName] = tenant_name if tenant_name
|
32
|
+
|
33
|
+
reply = Yao.default_client.default.post('/v2.0/tokens') do |req|
|
34
|
+
req.body = authinfo.to_json
|
35
|
+
req.headers['Content-Type'] = 'application/json'
|
36
|
+
end
|
37
|
+
|
38
|
+
body = reply.body["access"]
|
39
|
+
|
40
|
+
token = Token.new(body["token"])
|
41
|
+
token.register_endpoints(body["serviceCatalog"])
|
42
|
+
return token
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Token
|
47
|
+
def initialize(token_data)
|
48
|
+
@token = token_data["id"]
|
49
|
+
@issued_at = Time.parse token_data["issued_at"]
|
50
|
+
@expire_at = Time.parse token_data["expires"]
|
51
|
+
|
52
|
+
@endpoints = {}
|
53
|
+
end
|
54
|
+
attr_accessor :token, :issued_at, :expire_at, :endpoints
|
55
|
+
alias expires expire_at
|
56
|
+
|
57
|
+
def register_endpoints(_endpoints)
|
58
|
+
return unless _endpoints
|
59
|
+
|
60
|
+
_endpoints.each do |endpoint_data|
|
61
|
+
key = endpoint_data["type"]
|
62
|
+
value = if d = endpoint_data["endpoints"].first
|
63
|
+
d["publicURL"]
|
64
|
+
else
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
if value
|
68
|
+
@endpoints[key] = value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
Yao.default_client.register_endpoints(@endpoints, token: @token)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/yao/client.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'yao'
|
2
|
+
require 'yao/config'
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
require 'yao/faraday_middlewares'
|
6
|
+
|
7
|
+
module Yao
|
8
|
+
module Client
|
9
|
+
class ClientSet
|
10
|
+
def initialize
|
11
|
+
@pool = {}
|
12
|
+
end
|
13
|
+
attr_reader :pool
|
14
|
+
|
15
|
+
%w(default compute network image metering volume orchestration identity).each do |type|
|
16
|
+
define_method(type) do
|
17
|
+
self.pool[type]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def register_endpoints(endpoints, token: nil)
|
22
|
+
endpoints.each_pair do |type, endpoint|
|
23
|
+
# XXX: neutron just have v2.0 API and endpoint may not have version prefix
|
24
|
+
if type == "network" && URI.parse(endpoint).path == "/"
|
25
|
+
endpoint = File.join(endpoint, "v2.0")
|
26
|
+
end
|
27
|
+
|
28
|
+
self.pool[type] = Yao::Client.gen_client(endpoint, token: token)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
attr_accessor :default_client
|
35
|
+
|
36
|
+
def gen_client(endpoint, token: nil)
|
37
|
+
Faraday.new( endpoint ) do |f|
|
38
|
+
f.request :url_encoded
|
39
|
+
f.request :json
|
40
|
+
|
41
|
+
if token
|
42
|
+
f.request :os_token, token
|
43
|
+
end
|
44
|
+
|
45
|
+
f.response :json, :content_type => /\bjson$/
|
46
|
+
f.response :logger
|
47
|
+
|
48
|
+
f.adapter Faraday.default_adapter
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset_client(new_endpoint=nil)
|
53
|
+
set = ClientSet.new
|
54
|
+
set.register_endpoints("default" => (new_endpoint || Yao.config.endpoint))
|
55
|
+
self.default_client = set
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
Yao.config.param :auth_url, nil do |endpoint|
|
60
|
+
if endpoint
|
61
|
+
Yao::Client.reset_client(endpoint)
|
62
|
+
Yao::Auth.try_new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.default_client
|
68
|
+
Yao::Client.default_client
|
69
|
+
end
|
70
|
+
end
|
data/lib/yao/config.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'yao'
|
2
|
+
|
3
|
+
module Yao
|
4
|
+
class Config
|
5
|
+
def _configuration_defaults
|
6
|
+
@_configuration_defaults ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def _configuration_hooks
|
10
|
+
@_configuration_hooks ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def configuration
|
14
|
+
@configuration ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def param(name, default, &hook)
|
18
|
+
raise("Duplicate definition of #{name}") if self.respond_to?(name)
|
19
|
+
|
20
|
+
name = name.to_sym
|
21
|
+
_configuration_defaults[name] = default
|
22
|
+
_configuration_hooks[name] = hook if block_given?
|
23
|
+
self.define_singleton_method(name) do |*a|
|
24
|
+
case a.size
|
25
|
+
when 0
|
26
|
+
configuration[name] || _configuration_defaults[name]
|
27
|
+
when 1
|
28
|
+
set(name, a.first)
|
29
|
+
else
|
30
|
+
raise ArgumentError, "wrong number of arguments (#{a.size} for 0, 1)"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def set(name, value)
|
36
|
+
raise("Undefined config key #{name}") unless self.respond_to?(name)
|
37
|
+
configuration[name.to_sym] = value
|
38
|
+
_configuration_hooks[name].call(value) if _configuration_hooks[name]
|
39
|
+
value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.config(&blk)
|
44
|
+
@__config ||= Config.new
|
45
|
+
@__config.instance_eval(&blk) if blk
|
46
|
+
@__config
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.configure(&blk)
|
50
|
+
config &blk
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
class Faraday::Request::OSToken
|
4
|
+
def initialize(app, token)
|
5
|
+
@app = app
|
6
|
+
@token = token
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:request_headers]['X-Auth-Token'] = @token
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
Faraday::Request.register_middleware os_token: -> { Faraday::Request::OSToken }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
unless defined? OpenStack
|
2
|
+
module OpenStack
|
3
|
+
end
|
4
|
+
|
5
|
+
Yao = OpenStack
|
6
|
+
|
7
|
+
# XXX: Some case, 'yao/version' is pre-required and
|
8
|
+
# will delete Yao::VERSION const by reassign in L5
|
9
|
+
unless require('yao/version')
|
10
|
+
load 'yao/version.rb'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'yao'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'yao/resources/restfully_accessible'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Yao::Resources
|
5
|
+
class Base
|
6
|
+
def self.friendly_attributes(*names)
|
7
|
+
names.map(&:to_s).each do |name|
|
8
|
+
define_method(name) do
|
9
|
+
self[name]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.map_attribute_to_attribute(k_and_v)
|
15
|
+
as_json, as_method = *k_and_v.to_a.first.map(&:to_s)
|
16
|
+
define_method(as_method) do
|
17
|
+
self[as_json]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.map_attribute_to_resource(k_and_v)
|
22
|
+
_name, klass = *k_and_v.to_a.first
|
23
|
+
name = _name.to_s
|
24
|
+
define_method(name) do
|
25
|
+
self[[name, klass].join("__")] ||= klass.new(self[name])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.map_attribute_to_resources(k_and_v)
|
30
|
+
_name, klass = *k_and_v.to_a.first
|
31
|
+
name = _name.to_s
|
32
|
+
define_method(name) do
|
33
|
+
self[[name, klass].join("__")] ||= self[name].map {|d|
|
34
|
+
klass.new(d)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(data_via_json)
|
40
|
+
@data = data_via_json
|
41
|
+
end
|
42
|
+
|
43
|
+
def [](name)
|
44
|
+
@data[name]
|
45
|
+
end
|
46
|
+
|
47
|
+
def []=(name, value)
|
48
|
+
@data[name] = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def id
|
52
|
+
self["id"]
|
53
|
+
end
|
54
|
+
|
55
|
+
def created
|
56
|
+
if date = self["created"]
|
57
|
+
Time.parse(date)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def updated
|
62
|
+
if date = self["updated"]
|
63
|
+
Time.parse(date)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
extend RestfullyAccessible
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Flavor < Base
|
3
|
+
friendly_attributes :name, :vcpus, :disk, :swap
|
4
|
+
map_attribute_to_attribute "os-flavor-access:is_public" => :public?
|
5
|
+
map_attribute_to_attribute "OS-FLV-DISABLED:disabled" => :disabled?
|
6
|
+
|
7
|
+
def ram(unit='M')
|
8
|
+
case unit
|
9
|
+
when 'M'
|
10
|
+
self["ram"]
|
11
|
+
when 'G'
|
12
|
+
self["ram"] / 1024.0
|
13
|
+
end
|
14
|
+
end
|
15
|
+
alias memory ram
|
16
|
+
|
17
|
+
self.service = "compute"
|
18
|
+
self.resource_name = "flavor"
|
19
|
+
self.resources_name = "flavors"
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Hypervisor < Base
|
3
|
+
friendly_attributes :hypervisor_hostname, :hypervisor_type, :hypervisor_version, :running_vms, :current_workload
|
4
|
+
:vcpus, :vcpus_used,
|
5
|
+
:memory_mb, :memory_mb_used, :free_disk_gb,
|
6
|
+
:local_gb, :local_gb_used, :free_disk_gb
|
7
|
+
|
8
|
+
def cpu_info
|
9
|
+
JSON.parse self["cpu_info"]
|
10
|
+
end
|
11
|
+
|
12
|
+
alias hostname hypervisor_hostname
|
13
|
+
alias type hypervisor_hostname
|
14
|
+
alias version hypervisor_version
|
15
|
+
|
16
|
+
self.service = "compute"
|
17
|
+
self.resource_name = "os-hypervisor"
|
18
|
+
self.resources_name = "os-hypervisors"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yao/resources/metadata_available'
|
2
|
+
module Yao::Resources
|
3
|
+
class Image < Base
|
4
|
+
friendly_attributes :name, :status, :progress, :metadata
|
5
|
+
map_attribute_to_attribute :minDisk => :min_disk
|
6
|
+
map_attribute_to_attribute :minRam => :min_ram
|
7
|
+
|
8
|
+
def size(unit=nil)
|
9
|
+
size = self["OS-EXT-IMG-SIZE:size"]
|
10
|
+
case unit
|
11
|
+
when 'K'
|
12
|
+
size / 1024.0
|
13
|
+
when 'M'
|
14
|
+
size / 1024.0 / 1024.0
|
15
|
+
when 'G'
|
16
|
+
size / 1024.0 / 1024.0 / 1024.0
|
17
|
+
else
|
18
|
+
size
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
self.service = "compute"
|
23
|
+
self.resource_name = "image"
|
24
|
+
self.resources_name = "images"
|
25
|
+
|
26
|
+
extend MetadataAvailable
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Keypair < Base
|
3
|
+
friendly_attributes :name, :public_key, :fingerprint
|
4
|
+
|
5
|
+
self.service = "compute"
|
6
|
+
self.resource_name = "os-keypair"
|
7
|
+
self.resources_name = "os-keypairs"
|
8
|
+
|
9
|
+
def self.list
|
10
|
+
super.map{|r| r[resource_name_in_json] }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
module MetadataAvailable
|
3
|
+
def list_metadata(id)
|
4
|
+
GET(metadata_path(id)).body["metadata"]
|
5
|
+
end
|
6
|
+
|
7
|
+
def create_metadata(id, metadata)
|
8
|
+
res = POST(metadata_path(id)) do |req|
|
9
|
+
req.body = {"metadata" => metadata}.to_json
|
10
|
+
req.headers['Content-Type'] = 'application/json'
|
11
|
+
end
|
12
|
+
res.body["metadata"]
|
13
|
+
end
|
14
|
+
alias append_metadata create_metadata
|
15
|
+
|
16
|
+
def update_metadata(id, metadata)
|
17
|
+
res = PUT(metadata_path(id)) do |req|
|
18
|
+
req.body = {"metadata" => metadata}.to_json
|
19
|
+
req.headers['Content-Type'] = 'application/json'
|
20
|
+
end
|
21
|
+
res.body["metadata"]
|
22
|
+
end
|
23
|
+
alias replace_metadata update_metadata
|
24
|
+
|
25
|
+
def get_metadata(id, key)
|
26
|
+
GET(metadata_key_path(id, key)).body["meta"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_metadata(id, key, value)
|
30
|
+
res = PUT(metadata_key_path(id, key)) do |req|
|
31
|
+
req.body = {"meta" => {key => value}}.to_json
|
32
|
+
req.headers['Content-Type'] = 'application/json'
|
33
|
+
end
|
34
|
+
res.body["meta"]
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_metadata(id, key)
|
38
|
+
DELETE(metadata_key_path(id, key)).body
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def metadata_path(id)
|
43
|
+
["servers", id, "metadata"].join("/")
|
44
|
+
end
|
45
|
+
|
46
|
+
def metadata_key_path(id, key)
|
47
|
+
["servers", id, "metadata", key].join("/")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Network < Base
|
3
|
+
friendly_attributes :name, :status, :shared, :tenant_id, :subnets, :admin_state_up
|
4
|
+
map_attribute_to_attribute "provider:physical_network" => :physical_network
|
5
|
+
map_attribute_to_attribute "provider:network_type" => :type
|
6
|
+
map_attribute_to_attribute "provider:segmentation_id" => :segmentation_id
|
7
|
+
|
8
|
+
alias shared? shared
|
9
|
+
|
10
|
+
self.service = "network"
|
11
|
+
self.resource_name = "network"
|
12
|
+
self.resources_name = "networks"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Port < Base
|
3
|
+
friendly_attributes :name, :mac_address, :status, :allowed_address_pairs,
|
4
|
+
:device_owner, :fixed_ips, :security_groups, :device_id,
|
5
|
+
:network_id, :tenant_id, :admin_state_up
|
6
|
+
map_attribute_to_attribute "binding:host_id" => :host_id
|
7
|
+
|
8
|
+
def primary_ip
|
9
|
+
fixed_ips.first["ip_address"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def primary_subnet
|
13
|
+
Yao::Subnet.find fixed_ips.first["subnet_id"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def network
|
17
|
+
Yao::Network.find network_id
|
18
|
+
end
|
19
|
+
|
20
|
+
self.service = "network"
|
21
|
+
self.resource_name = "port"
|
22
|
+
self.resources_name = "ports"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Yao::Resources
|
4
|
+
module RestfullyAccessible
|
5
|
+
def self.extended(base)
|
6
|
+
base.class_eval do
|
7
|
+
class << self
|
8
|
+
attr_reader :client
|
9
|
+
attr_accessor :resource_name, :resources_name
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
%w(get post put delete).each do |method_name|
|
13
|
+
def_delegator :client, method_name, method_name.upcase
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def service=(name)
|
20
|
+
@service = name
|
21
|
+
@client = Yao.default_client.pool[name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def service
|
25
|
+
@service
|
26
|
+
end
|
27
|
+
|
28
|
+
# restful methods
|
29
|
+
def list
|
30
|
+
return_resources(GET(resources_name).body[resources_name_in_json])
|
31
|
+
end
|
32
|
+
|
33
|
+
def list_detail
|
34
|
+
return_resources(GET([resources_name, "detail"].join("/")).body[resources_name_in_json])
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(id_or_permalink)
|
38
|
+
res = if id_or_permalink =~ /^https?:\/\//
|
39
|
+
GET(id_or_permalink)
|
40
|
+
else
|
41
|
+
GET([resources_name, id_or_permalink].join("/"))
|
42
|
+
end
|
43
|
+
return_resource(res.body[resource_name_in_json])
|
44
|
+
end
|
45
|
+
alias find get
|
46
|
+
|
47
|
+
def create(resource_params)
|
48
|
+
params = {
|
49
|
+
resource_name_in_json => resource_params
|
50
|
+
}
|
51
|
+
res = POST(resources_name) do |req|
|
52
|
+
req.body = params.to_json
|
53
|
+
req.headers['Content-Type'] = 'application/json'
|
54
|
+
end
|
55
|
+
return_resource(res.body[resource_name_in_json])
|
56
|
+
end
|
57
|
+
|
58
|
+
def update(id, resource_params)
|
59
|
+
params = {
|
60
|
+
resource_name_in_json => resource_params
|
61
|
+
}
|
62
|
+
res = PUT([resources_name, id].join("/")) do |req|
|
63
|
+
req.body = params.to_json
|
64
|
+
req.headers['Content-Type'] = 'application/json'
|
65
|
+
end
|
66
|
+
return_resource(res.body[resource_name_in_json])
|
67
|
+
end
|
68
|
+
|
69
|
+
def destroy(id)
|
70
|
+
res = DELETE([resources_name, id].join("/"))
|
71
|
+
res.body
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def resource_name_in_json
|
76
|
+
@resource_name_in_json ||= resource_name.sub(/^os-/, "").tr("-", "_")
|
77
|
+
end
|
78
|
+
|
79
|
+
def resources_name_in_json
|
80
|
+
@resources_name_in_json ||= resources_name.sub(/^os-/, "").tr("-", "_")
|
81
|
+
end
|
82
|
+
|
83
|
+
def return_resource(d)
|
84
|
+
new(d)
|
85
|
+
end
|
86
|
+
|
87
|
+
def return_resources(arr)
|
88
|
+
arr.map{|d| return_resource(d) }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'yao/resources/security_group_rule'
|
2
|
+
module Yao::Resources
|
3
|
+
class SecurityGroup < Base
|
4
|
+
friendly_attributes :name, :description, :tenant_id
|
5
|
+
|
6
|
+
def rules
|
7
|
+
self[["rules", SecurityGroupRule].join("__")] ||= (case self.class.service
|
8
|
+
when "compute"
|
9
|
+
self["rules"].map{|r| SecurityGroupRule.new(r) }
|
10
|
+
when "network"
|
11
|
+
self["security_group_rules"].map{|r| SecurityGroupRule.new(r) }
|
12
|
+
end)
|
13
|
+
end
|
14
|
+
|
15
|
+
self.service = "compute"
|
16
|
+
self.resource_name = "os-security-group"
|
17
|
+
self.resources_name = "os-security-groups"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Yao.config.param :security_group_service, "compute" do |service|
|
22
|
+
case service
|
23
|
+
when "compute"
|
24
|
+
Yao::Resources::SecurityGroup.service = service
|
25
|
+
Yao::Resources::SecurityGroup.resource_name = "os-security-group"
|
26
|
+
Yao::Resources::SecurityGroup.resources_name = "os-security-groups"
|
27
|
+
|
28
|
+
Yao::Resources::SecurityGroupRule.service = service
|
29
|
+
Yao::Resources::SecurityGroupRule.resource_name = "os-security-group-rule"
|
30
|
+
Yao::Resources::SecurityGroupRule.resources_name = "os-security-group-rules"
|
31
|
+
when "network"
|
32
|
+
Yao::Resources::SecurityGroup.service = service
|
33
|
+
Yao::Resources::SecurityGroup.resource_name = "security-group"
|
34
|
+
Yao::Resources::SecurityGroup.resources_name = "security-groups"
|
35
|
+
|
36
|
+
Yao::Resources::SecurityGroupRule.service = service
|
37
|
+
Yao::Resources::SecurityGroupRule.resource_name = "security-group-rule"
|
38
|
+
Yao::Resources::SecurityGroupRule.resources_name = "security-group-rules"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'yao/resources/security_group'
|
2
|
+
module Yao::Resources
|
3
|
+
class SecurityGroupRule < Base
|
4
|
+
friendly_attributes :ethertype
|
5
|
+
|
6
|
+
def self.define_attribute_with_guard(_name, _guard_name)
|
7
|
+
name = _name.to_s
|
8
|
+
guard_name = _guard_name.to_s
|
9
|
+
define_method name do
|
10
|
+
self[name] || self[guard_name]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
define_attribute_with_guard :port_range_max, :from_port
|
15
|
+
define_attribute_with_guard :port_range_min, :to_port
|
16
|
+
define_attribute_with_guard :protocol, :ip_protocol
|
17
|
+
define_attribute_with_guard :security_group_id, :parent_group_id
|
18
|
+
|
19
|
+
def security_group
|
20
|
+
SecurityGroup.find(security_group_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def port
|
24
|
+
if port_range_max == port_range_min
|
25
|
+
port_range_max
|
26
|
+
else
|
27
|
+
port_range
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def remote_ip_cidr
|
32
|
+
if cidr = self["remote_ip_prefix"]
|
33
|
+
cidr
|
34
|
+
elsif ip_range = self["ip_range"]
|
35
|
+
ip_range["cidr"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def port_range
|
40
|
+
port_range_max..port_range_min
|
41
|
+
end
|
42
|
+
|
43
|
+
def remote_group
|
44
|
+
return nil if self["remote_group_id"].nil? && (self["group"].nil? || self["group"].empty?)
|
45
|
+
|
46
|
+
SecurityGroup.new(
|
47
|
+
{"id" => self["remote_group_id"]}.merge(self["group"] || {})
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
self.service = "compute"
|
52
|
+
self.resource_name = "os-security-group-rule"
|
53
|
+
self.resources_name = "os-security-group-rules"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'yao/resources/metadata_available'
|
2
|
+
module Yao::Resources
|
3
|
+
class Server < Base
|
4
|
+
friendly_attributes :addresses, :metadata, :name, :progress,
|
5
|
+
:status, :tenant_id, :user_id, :key_name
|
6
|
+
map_attribute_to_attribute :hostId => :host_id
|
7
|
+
map_attribute_to_resource :flavor => Flavor
|
8
|
+
map_attribute_to_resource :image => Image
|
9
|
+
map_attribute_to_resources :security_groups => SecurityGroup
|
10
|
+
|
11
|
+
self.service = "compute"
|
12
|
+
self.resource_name = "server"
|
13
|
+
self.resources_name = "servers"
|
14
|
+
|
15
|
+
extend MetadataAvailable
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Yao::Resources
|
2
|
+
class Subnet < Base
|
3
|
+
friendly_attributes :name, :cidr, :gateway_ip, :network_id, :tenant_id, :ip_version,
|
4
|
+
:dns_nameservers, :host_routes, :enable_dhcp
|
5
|
+
|
6
|
+
def allocation_pools
|
7
|
+
self["allocation_pools"].map do |pool|
|
8
|
+
pool["start"]..pool["end"]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def network
|
13
|
+
Yao::Network.find network_id
|
14
|
+
end
|
15
|
+
|
16
|
+
alias dhcp_enabled? enable_dhcp
|
17
|
+
|
18
|
+
self.service = "network"
|
19
|
+
self.resource_name = "subnet"
|
20
|
+
self.resources_name = "subnets"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Yao
|
2
|
+
module Resources
|
3
|
+
require "yao/resources/base"
|
4
|
+
|
5
|
+
autoload :Server, "yao/resources/server"
|
6
|
+
autoload :Flavor, "yao/resources/flavor"
|
7
|
+
autoload :Image, "yao/resources/image"
|
8
|
+
autoload :SecurityGroup, "yao/resources/security_group"
|
9
|
+
autoload :SecurityGroupRule, "yao/resources/security_group_rule"
|
10
|
+
autoload :Hypervisor, "yao/resources/hypervisor"
|
11
|
+
autoload :Keypair, "yao/resources/keypair"
|
12
|
+
autoload :FloatingIP, "yao/resources/floating_ip"
|
13
|
+
autoload :Network, "yao/resources/network"
|
14
|
+
autoload :Subnet, "yao/resources/subnet"
|
15
|
+
autoload :Port, "yao/resources/port"
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.const_missing(name)
|
20
|
+
new_klass = Yao::Resources.const_get(name)
|
21
|
+
Yao.const_set(name, new_klass)
|
22
|
+
rescue NameError
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
data/lib/yao/version.rb
ADDED
data/lib/yao.rb
ADDED
data/yao.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'yao/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "yao"
|
8
|
+
spec.version = Yao::VERSION
|
9
|
+
spec.authors = ["Uchio, KONDO"]
|
10
|
+
spec.email = ["udzura@udzura.jp"]
|
11
|
+
spec.summary = %q{Yet Another OpenStack API Wrapper that rocks!!}
|
12
|
+
spec.description = %q{YAO is a Yet Another OpenStack API Wrapper that rocks!!}
|
13
|
+
spec.homepage = "https://github.com/udzura/yao"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "json"
|
22
|
+
spec.add_dependency "faraday"
|
23
|
+
spec.add_dependency "faraday_middleware"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", ">= 1.10"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "test-unit", ">= 3"
|
28
|
+
spec.add_development_dependency "test-unit-rr"
|
29
|
+
spec.add_development_dependency "power_assert"
|
30
|
+
spec.add_development_dependency "pry"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yao
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2.rc3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Uchio, KONDO
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday_middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: test-unit
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: test-unit-rr
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: power_assert
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: YAO is a Yet Another OpenStack API Wrapper that rocks!!
|
140
|
+
email:
|
141
|
+
- udzura@udzura.jp
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- Gemfile
|
148
|
+
- LICENSE.txt
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- lib/yao.rb
|
152
|
+
- lib/yao/auth.rb
|
153
|
+
- lib/yao/client.rb
|
154
|
+
- lib/yao/config.rb
|
155
|
+
- lib/yao/faraday_middlewares.rb
|
156
|
+
- lib/yao/is_openstack_client.rb
|
157
|
+
- lib/yao/resources.rb
|
158
|
+
- lib/yao/resources/base.rb
|
159
|
+
- lib/yao/resources/flavor.rb
|
160
|
+
- lib/yao/resources/floating_ip.rb
|
161
|
+
- lib/yao/resources/hypervisor.rb
|
162
|
+
- lib/yao/resources/image.rb
|
163
|
+
- lib/yao/resources/keypair.rb
|
164
|
+
- lib/yao/resources/metadata_available.rb
|
165
|
+
- lib/yao/resources/network.rb
|
166
|
+
- lib/yao/resources/port.rb
|
167
|
+
- lib/yao/resources/restfully_accessible.rb
|
168
|
+
- lib/yao/resources/security_group.rb
|
169
|
+
- lib/yao/resources/security_group_rule.rb
|
170
|
+
- lib/yao/resources/server.rb
|
171
|
+
- lib/yao/resources/subnet.rb
|
172
|
+
- lib/yao/version.rb
|
173
|
+
- yao.gemspec
|
174
|
+
homepage: https://github.com/udzura/yao
|
175
|
+
licenses:
|
176
|
+
- MIT
|
177
|
+
metadata: {}
|
178
|
+
post_install_message:
|
179
|
+
rdoc_options: []
|
180
|
+
require_paths:
|
181
|
+
- lib
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">"
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 1.3.1
|
192
|
+
requirements: []
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 2.2.3
|
195
|
+
signing_key:
|
196
|
+
specification_version: 4
|
197
|
+
summary: Yet Another OpenStack API Wrapper that rocks!!
|
198
|
+
test_files: []
|