yao 0.0.2.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|