pec 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a6e5a3923304e41d105e24cf8891ccd93f3bb805
4
+ data.tar.gz: 0552a19993b6d2489129c5f370ca2b6f0e1cf4ed
5
+ SHA512:
6
+ metadata.gz: 312f3f168a0a338878d20fedf851ae4669fec84755da69b5d86b69964c358e962bb74a796bdfed6aea89fa9307811377b0dd0fd483ec3c91c98fc8a0e531dc67
7
+ data.tar.gz: 5377b587b2813d2086864ba6ec3a1f31a9c5cb098f5b2acab4fa8c3c49cf23bc880aec677810178e0fab8f06acbffd6431ba6d41f670db499b1edc4d7287484d
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vendor
11
+ *.yaml
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pec.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Pec
2
+
3
+ OpenStackにおいて複数サーバの起動や、
4
+ DHCPサーバがない状況でのIP自動採番を実現します。
5
+
6
+ ## インストール方法
7
+
8
+
9
+ $ gem install pec
10
+
11
+ ## 使用方法
12
+ ### コマンド
13
+ 実行ディレクトリに存在するPec.yamlに基づきホストを作成します。
14
+ ホスト名が指定された場合はそのホストのみ作成します。
15
+
16
+ $ pec up <hostname>
17
+
18
+ $ pec destroy <hostname>
19
+
20
+ ### 設定ファイル
21
+ [fog](https://github.com/fog/fog)を利用しているので、fogの設定を行ってください。
22
+
23
+ ```
24
+ % cat ~/.fog
25
+ default:
26
+ openstack_auth_url: "http://your-openstack-endpoint/v2.0/tokens"
27
+ openstack_username: "admin"
28
+ openstack_tenant: "admin"
29
+ openstack_api_key: "admin-no-password"
30
+ ```
31
+
32
+
33
+ `~/Pec.yaml`
34
+ ```
35
+ pyama-test001:
36
+ image: centos-7.1_chef-12.3_puppet-3.7
37
+ flavor: m1.small
38
+ networks:
39
+ eth0:
40
+ bootproto: static
41
+ ip_address: 157.7.190.128/26
42
+ gateway: 157.7.190.129
43
+ dns1: 8.8.8.8
44
+ dns2: 8.8.8.8
45
+ eth1:
46
+ bootproto: static
47
+ ip_address: 10.51.113.0/24
48
+ dns1: 8.8.8.8
49
+ dns2: 8.8.8.8
50
+ user_data:
51
+ hostname: pyama-test001
52
+ fqdn: pyama-test001.ikemen.com
53
+ repo_releasever: 7.1.1503
54
+ pyama-test002:
55
+ image: centos-7.1_chef-12.3_puppet-3.7
56
+ flavor: m1.midium
57
+ networks:
58
+ eth0:
59
+ bootproto: static
60
+ ip_address: 157.7.190.128/26
61
+ gateway: 157.7.190.129
62
+ dns1: 8.8.8.8
63
+ dns2: 8.8.8.8
64
+ eth1:
65
+ bootproto: static
66
+ ip_address: 10.51.113.0/24
67
+ dns1: 8.8.8.8
68
+ dns2: 8.8.8.8
69
+ user_data:
70
+ hostname: pyama-test002
71
+ fqdn: pyama-test002.ikemen.com
72
+ repo_releasever: 7.1.1503
73
+ ```
74
+ `image`,`flavor`は必須項目です。
75
+ `networks`について指定する場合は、`bootproto`,`ip_address`が必須です。`ip_address`は`xxx.xxx.xxx.xxx/yy`の方式を想定しており、ネットワークアドレスが指定された場合、そのサブネットで未使用のアドレスを自動で採番します。
76
+ `user_data`については`nova api`にネットワーク設定を加えて引き渡すため、cloud-init記法に準拠します。
77
+
78
+
79
+ ## Author
80
+ * pyama86
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pec"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/pec ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pec'
3
+ Pec::CLI.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/pec ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "pec"
data/lib/pec.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'fog'
2
+ require 'ip'
3
+ require "pec/version"
4
+ require "pec/query"
5
+ require "pec/vm_director"
6
+ require "pec/configure"
7
+ require "pec/configure/host"
8
+ require "pec/configure/ethernet"
9
+ require "pec/configure/user_data"
10
+ require "pec/compute/server"
11
+ require "pec/compute/flavor"
12
+ require "pec/compute/image"
13
+ require "pec/compute/security_group"
14
+ require "pec/network/port"
15
+ require "pec/network/subnet"
16
+ require "pec/cli"
17
+
18
+ module Pec
19
+ end
20
+
data/lib/pec/cli.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'pec'
2
+ require 'thor'
3
+ module Pec
4
+ class CLI < Thor
5
+ option :filename, type: :string, aliases: "-f"
6
+ desc 'up', 'create vm by Pec.yaml'
7
+ def up(host_name = nil)
8
+ config = Pec::Configure.new
9
+ config.load("Pec.yaml")
10
+ director = Pec::VmDirector.new
11
+ config.each do |host|
12
+ next if !host_name.nil? && host.name != host_name
13
+ puts "can't create server:#{host.name}" unless director.make(host)
14
+ end if config
15
+ end
16
+ desc "destroy", "delete vm"
17
+ def destroy(name)
18
+ Pec::Compute::Server.new.destroy!(name) if yes?("#{name}: Are you sure you want to destroy the '#{name}' VM? [y/N]")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Pec
2
+ class Compute
3
+ class Flavor
4
+ include Query
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Pec
2
+ class Compute
3
+ class Image
4
+ include Query
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Pec
2
+ class Compute
3
+ class Security_Group
4
+ include Query
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ require 'json'
2
+ module Pec
3
+ class Compute
4
+ class Server
5
+ include Query
6
+ def create(name, image_ref, flavor_ref, ports, options)
7
+ if exists?(name)
8
+ puts "skip create server! name:#{name} is exists!"
9
+ return true
10
+ end
11
+
12
+ networks = ports.map do |port|
13
+ if port.used?
14
+ puts "port-id:#{port.id} ip-addr:#{port.ip_address} in used"
15
+ return false
16
+ end
17
+ { net_id: port.network_id, fixed_ip: port.ip_address, port_id: port.id }
18
+ end if ports
19
+
20
+ options.merge!({ 'nics' => networks })
21
+ response = Fog::Compute[:openstack].create_server(name, image_ref, flavor_ref, options)
22
+ if response[:status] == 202
23
+ puts "success create for server_name:#{name}"
24
+ end
25
+ true
26
+ rescue Excon::Errors::Conflict,Excon::Errors::BadRequest => e
27
+ JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
28
+ false
29
+ end
30
+
31
+ def exists?(server_name)
32
+ fetch(server_name)
33
+ end
34
+
35
+ def destroy!(server_name)
36
+ server = fetch(server_name)
37
+ unless server
38
+ puts "server_name:#{server_name} is not fond!"
39
+ return
40
+ end
41
+
42
+ response = Fog::Compute[:openstack].delete_server(server["id"]) if server
43
+ if response && response[:status] == 204
44
+ puts "server_name:#{server_name} is deleted!"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,22 @@
1
+ require 'yaml'
2
+ module Pec
3
+ class Configure
4
+ include Enumerable
5
+
6
+ def load(file_name)
7
+ YAML.load_file(file_name).to_hash.each do |config|
8
+ host = Pec::Configure::Host.load(config)
9
+ @configure ||= []
10
+ @configure << host if host
11
+ end
12
+ rescue Psych::SyntaxError => e
13
+ puts e
14
+ end
15
+
16
+ def each
17
+ @configure.each do |config|
18
+ yield config
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ module Pec
2
+ class Configure
3
+ class Ethernet
4
+ attr_reader :name, :bootproto, :ip_address, :options
5
+ def initialize(config)
6
+ @name = config[0];
7
+ @bootprot = config[1]["bootproto"];
8
+ @ip_address = config[1]["ip_address"];
9
+ @options = config[1].select do |k,v|
10
+ { k => v } if k != "bootproto" && k != "ip_address"
11
+ end
12
+ end
13
+
14
+ class << self
15
+ def load(name, config)
16
+ self.new(config) if check_require_key(name, config) && check_network_key(name, config)
17
+ end
18
+
19
+ def check_require_key(name, config)
20
+ err = %w(bootproto ip_address).find {|k| !config[1].key?(k)}
21
+ return true if err.nil?
22
+ puts "skip! #{name}: #{err} is required!"
23
+ false
24
+ end
25
+
26
+ def check_network_key(name, config)
27
+ net = config[1]
28
+ case
29
+ when (net["bootproto"] == "static" && net["ip_address"].nil?)
30
+ puts "skip! #{name}: ip_address is required by bootproto static"
31
+ return false
32
+ when (!net["bootproto"] == "static" && !net["bootproto"] == "dhcp")
33
+ puts "skip! #{name}: bootproto set the value dhcp or static"
34
+ return false
35
+ when (!net["bootproto"] == "static" && !net["bootproto"] == "dhcp")
36
+ puts "skip! #{name}: bootproto set the value dhcp or static"
37
+ return false
38
+ end
39
+ true
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ module Pec
2
+ class Configure
3
+ class Host
4
+ attr_reader :name, :image, :flavor,:security_group, :user_data, :networks
5
+ def initialize(config)
6
+ @name = config[0];
7
+ @image = config[1]["image"];
8
+ @flavor = config[1]["flavor"];
9
+ @security_group = config[1]["security_group"];
10
+ @user_data = config[1]["user_data"];
11
+ end
12
+
13
+ def append_network(network)
14
+ @networks ||= []
15
+ @networks << network
16
+ end
17
+
18
+ class << self
19
+ def load(config)
20
+ host = self.new(config) if check_require_key(config)
21
+ config[1]["networks"].each do |net|
22
+ net_config = Pec::Configure::Ethernet.load(config[0], net)
23
+ return nil unless net_config
24
+ host.append_network(net_config)
25
+ end if host && config[1]["networks"]
26
+ host
27
+ end
28
+
29
+ def check_require_key(config)
30
+ err = %w(image flavor).find {|r| !config[1].key?(r)}
31
+ return true if err.nil?
32
+ puts "skip! #{config[0]}: #{err} is required!"
33
+ false
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ require 'base64'
2
+ module Pec
3
+ class Configure
4
+ class UserData
5
+ class << self
6
+ def make(config, ports)
7
+ user_data = {}
8
+ user_data["write_files"] = make_port_content(config, ports) if ports
9
+ Base64.encode64("#cloud-config\n" + user_data.merge(config.user_data).to_yaml)
10
+ end
11
+
12
+ def make_port_content(config, ports)
13
+ config.networks.map do |ether|
14
+ port_content = {}
15
+ port_content["name"] = ether.name unless ether.options.key?('name')
16
+ port_content["device"] = ether.name unless ether.options.key?('device')
17
+ port_content["type"] = 'Ethernet' unless ether.options.key?('type')
18
+ port_content["onboot"] = "yes" unless ether.options.key?('onboot')
19
+
20
+ _path = "/etc/sysconfig/network-scripts/ifcfg-#{ether.name}" unless ether.options.key?('path')
21
+
22
+ port = ports.find {|p| p.name == ether.name}
23
+
24
+ if port
25
+ port_content["netmask"] = port.netmask
26
+ port_content["hwaddr"] = port.mac_address
27
+ port_content["ipaddr"] = port.ip_address
28
+ end
29
+ port_content.merge!(ether.options)
30
+ {
31
+ 'content' => port_content.map {|k,v| "#{k.upcase}=#{v}"}.join("\n"),
32
+ 'owner' => "root:root",
33
+ 'path' => _path,
34
+ 'permissions' => "0644"
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,78 @@
1
+ require 'json'
2
+ module Pec
3
+ class Network
4
+ class Port
5
+ attr_reader :name, :subnet
6
+ include Query
7
+ def initialize(name, ip_addr, subnet)
8
+ @name = name
9
+ @subnet = subnet
10
+ @config = fetch(ip_addr)
11
+ end
12
+
13
+ def fetch(ip_addr)
14
+ list.find {|p| p["fixed_ips"][0]["ip_address"] == ip_addr }
15
+ end
16
+
17
+ def exists?
18
+ !@config.nil?
19
+ end
20
+
21
+ def used?
22
+ @config && !@config["device_owner"].empty?
23
+ end
24
+
25
+ def id
26
+ @config["id"]
27
+ end
28
+
29
+ def mac_address
30
+ @config["mac_address"]
31
+ end
32
+
33
+ def ip_address
34
+ @config["fixed_ips"][0]["ip_address"]
35
+ end
36
+
37
+ def network_id
38
+ @config["network_id"]
39
+ end
40
+
41
+ def netmask
42
+ IP.new(@config["fixed_ips"][0]["ip_address"]).netmask.to_s
43
+ end
44
+
45
+ def create(ip)
46
+ options = {}
47
+ ## parameter is network address to dhcp
48
+ if ip.to_s != subnet["cidr"]
49
+ options = { fixed_ips: [{ subnet_id: @subnet["id"], ip_address: ip.to_addr}]}
50
+ end
51
+
52
+ res = Fog::Network[:openstack].create_port(@subnet["network_id"], options)
53
+
54
+ @config = res.data[:body]["port"] if res
55
+ @@_list['port'] ||= []
56
+ @@_list['port'] << @config
57
+ true
58
+ rescue Excon::Errors::Conflict => e
59
+ JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
60
+ false
61
+ end
62
+
63
+ def delete(port_id)
64
+ Fog::Network[:openstack].delete_port(port_id)
65
+ rescue Excon::Errors::Conflict => e
66
+ JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
67
+ false
68
+ end
69
+
70
+ def replace(ip)
71
+ delete(id)
72
+ @@_list['port'] = nil
73
+ create(ip)
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,10 @@
1
+ module Pec
2
+ class Network
3
+ class Subnet
4
+ include Query
5
+ def fetch(cidr)
6
+ list.find {|p| p["cidr"] == cidr }
7
+ end
8
+ end
9
+ end
10
+ end
data/lib/pec/query.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'fog'
3
+ module Pec
4
+ module Query
5
+ @@_list = Hash.new
6
+ def get_adapter
7
+ case
8
+ when self.class.name.include?('Network')
9
+ Fog::Network[:openstack]
10
+ when self.class.name.include?('Compute')
11
+ Fog::Compute[:openstack]
12
+ else
13
+ raise
14
+ end
15
+ end
16
+
17
+ def list
18
+ name = self.class.name.demodulize.downcase+"s"
19
+ @@_list[name] || get_adapter.send("list_#{name}").data[:body][name]
20
+ end
21
+
22
+ def fetch(name)
23
+ list.find {|s| s["name"] == name}
24
+ end
25
+
26
+ def get_ref(name)
27
+ response = fetch(name)
28
+ response["links"][0]["href"]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Pec
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,67 @@
1
+ module Pec
2
+ class VmDirector
3
+ def initialize
4
+ @subnet = Pec::Network::Subnet.new
5
+ @flavor = Pec::Compute::Flavor.new
6
+ @image = Pec::Compute::Image.new
7
+ @security_group = Pec::Compute::Security_Group.new
8
+ @compute = Pec::Compute::Server.new
9
+ end
10
+
11
+ def make(config)
12
+ ports = get_ports(config)
13
+ flavor_ref = get_flavor(config.flavor)
14
+ image_ref = get_image(config.image)
15
+ return false unless flavor_ref && image_ref
16
+ options = {
17
+ "user_data" => Pec::Configure::UserData.make(config, ports),
18
+ "security_groups" => config.security_group
19
+ }
20
+
21
+ @compute.create(config.name, image_ref, flavor_ref, ports, options)
22
+ end
23
+
24
+ def get_ports(config)
25
+ config.networks.map do |ether|
26
+ ip = IP.new(ether.ip_address)
27
+ _subnet = get_subnet(ip)
28
+ return false unless _subnet
29
+
30
+ _port = Pec::Network::Port.new(ether.name, ip.to_addr, _subnet)
31
+
32
+ res = case
33
+ when _port.exists? && !_port.used?
34
+ _port.replace(ip)
35
+ when !_port.exists?
36
+ _port.create(ip)
37
+ when _port.used?
38
+ false
39
+ end
40
+
41
+ unless res
42
+ puts "ip addess:#{ip.to_addr} can't create port!"
43
+ return false
44
+ end
45
+ _port
46
+ end if config.networks
47
+ end
48
+
49
+ def get_subnet(ip)
50
+ _subnet = @subnet.fetch(ip.network.to_s)
51
+ puts "ip addess:#{ip.to_addr} subnet not fond!" if _subnet.nil?
52
+ _subnet
53
+ end
54
+
55
+ def get_flavor(name)
56
+ flavor_ref = @flavor.get_ref(name)
57
+ puts "flavor:#{name} not fond!" if flavor_ref.nil?
58
+ flavor_ref
59
+ end
60
+
61
+ def get_image(name)
62
+ image_ref = @image.get_ref(name)
63
+ puts "image:#{name} not fond!" if image_ref.nil?
64
+ image_ref
65
+ end
66
+ end
67
+ end
data/pec.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pec"
8
+ spec.version = Pec::VERSION
9
+ spec.authors = ["kazuhiko yamashita"]
10
+ spec.email = ["pyama@pepabo.com"]
11
+
12
+ spec.summary = %q{openstack vm booter.}
13
+ spec.description = %q{openstac vm booter.}
14
+ spec.homepage = "http://ten-snapon.com"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+ spec.add_dependency 'fog'
22
+ spec.add_dependency 'thor'
23
+ spec.add_dependency 'ruby-ip'
24
+ spec.add_dependency 'activesupport'
25
+ spec.add_development_dependency "bundler", "~> 1.9"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - kazuhiko yamashita
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-06-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fog
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: thor
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: ruby-ip
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: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ description: openstac vm booter.
98
+ email:
99
+ - pyama@pepabo.com
100
+ executables:
101
+ - pec
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - README.md
109
+ - Rakefile
110
+ - bin/console
111
+ - bin/pec
112
+ - bin/setup
113
+ - exe/pec
114
+ - lib/pec.rb
115
+ - lib/pec/cli.rb
116
+ - lib/pec/compute/flavor.rb
117
+ - lib/pec/compute/image.rb
118
+ - lib/pec/compute/security_group.rb
119
+ - lib/pec/compute/server.rb
120
+ - lib/pec/configure.rb
121
+ - lib/pec/configure/ethernet.rb
122
+ - lib/pec/configure/host.rb
123
+ - lib/pec/configure/user_data.rb
124
+ - lib/pec/network/port.rb
125
+ - lib/pec/network/subnet.rb
126
+ - lib/pec/query.rb
127
+ - lib/pec/version.rb
128
+ - lib/pec/vm_director.rb
129
+ - pec.gemspec
130
+ homepage: http://ten-snapon.com
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.4.6
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: openstack vm booter.
154
+ test_files: []