pec 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a23835f633410abdb1ca9c614c3d8e386101c17d
4
- data.tar.gz: 7f3df00c0a75012a93898c33bc9b5f28eb213fa5
3
+ metadata.gz: 409aebdf8468165b18f5bf9e130a64c0e8d52e89
4
+ data.tar.gz: 79635469bbd61536714e08715cfafe4a9c5ab77e
5
5
  SHA512:
6
- metadata.gz: 2f05e20813ffd29318f0ae79608907412682b6aaa52371b7dce7d648351c470f4aba4aeea632020d5dc8b7ab85f6a7c02d2efff21619a33810c13703e6576557
7
- data.tar.gz: 24b4f770903b98f04c28896c749d8fc784f4896ef2eb13c45cab6db9cc402ee8073d623e97492279dd0a7ce0579d5f1e99746a17f1b0e3cbe803d93d7a6390f7
6
+ metadata.gz: 683b49175521024e1a3d617678efd3fdc4896a3905c1d25827c6fb0eb2b2be055ba6d971b1468b0572cb0d0f7c0437ee953ff2bec9ef51470ba875b61143c0da
7
+ data.tar.gz: 58be8b103ec3b6353d0eba896d31b1c4738dec33a6fc8f0b85f3710c5f3f70a63fd04b942306f9435901ad9349194fbf4b6bfaedbeba025f84dae8abe2ed1380
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -1,3 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
3
+ - 2.0.0
4
+ - 2.1.6
5
+ - 2.2.2
data/Gemfile CHANGED
@@ -12,3 +12,6 @@ group :development, :test do
12
12
  gem "rspec"
13
13
  gem "rake"
14
14
  end
15
+ group :test do
16
+ gem 'coveralls', :require => false
17
+ end
data/README.md CHANGED
@@ -1,25 +1,33 @@
1
1
  # Pec
2
-
2
+ [![Build Status](https://travis-ci.org/pyama86/pec.svg?branch=master)](https://travis-ci.org/pyama86/pec)
3
3
  OpenStackにおいて複数サーバの起動や、
4
4
  DHCPサーバがない状況でのIP自動採番を実現します。
5
5
 
6
- ## インストール方法
6
+ ## Install
7
7
 
8
8
 
9
9
  $ gem install pec
10
10
 
11
- ## 使用方法
12
- ### コマンド
13
- 実行ディレクトリに存在するPec.yamlに基づきホストを作成します。
14
- ホスト名が指定された場合はそのホストのみ作成します。
11
+ ## Usage
12
+
13
+ 定義ファイル作成
14
+
15
+ $ pec init
16
+
17
+ ```
18
+ create - /Pec.yaml
19
+ create - /user_datas/web_server.yaml.sample
20
+ ```
21
+
22
+ Pec.yamlに基づきホストを作成します。
23
+ ホスト名が指定された場合はそのホストのみ作成、削除します。
15
24
 
16
25
  $ pec up <hostname>
17
26
 
18
27
  $ pec destroy <hostname>
19
28
 
20
- ### 設定ファイル
21
- [fog](https://github.com/fog/fog)を利用しているので、fogの設定を行ってください。
22
-
29
+ ### Configure
30
+ #### ~/.fog
23
31
  ```
24
32
  % cat ~/.fog
25
33
  default:
@@ -30,7 +38,7 @@ default:
30
38
  ```
31
39
 
32
40
 
33
- `実行ディレクトリ/Pec.yaml`にVMの設定を実施します。
41
+ #### Pec.yaml
34
42
  ```
35
43
  pyama-test001:
36
44
  image: centos-7.1_chef-12.3_puppet-3.7
@@ -43,10 +51,13 @@ pyama-test001:
43
51
  dns1: 8.8.8.8
44
52
  dns2: 8.8.8.8
45
53
  eth1:
46
- bootproto: static
47
- ip_address: 20.2.2.0/24
48
- dns1: 8.8.8.8
49
- dns2: 8.8.8.8
54
+ bootproto: dhcp
55
+ security_group:
56
+ - default
57
+ - ssh
58
+ templates:
59
+ - base.yaml
60
+ - webserver.yaml
50
61
  user_data:
51
62
  hostname: pyama-test001
52
63
  fqdn: pyama-test001.ikemen.com
@@ -54,28 +65,30 @@ pyama-test001:
54
65
  pyama-test002:
55
66
  image: centos-7.1_chef-12.3_puppet-3.7
56
67
  flavor: m1.midium
57
- networks:
58
- eth0:
59
- bootproto: static
60
- ip_address: 10.0.0.64/26
61
- gateway: 10.0.0.127
62
- dns1: 8.8.8.8
63
- dns2: 8.8.8.8
64
- path: /etc/sysconfig/network-scripts/ifcfg-bond0
65
- eth1:
66
- bootproto: dhcp
67
- user_data:
68
- hostname: pyama-test002
69
- fqdn: pyama-test002.ikemen.com
70
- repo_releasever: 7.1.1503
68
+ ・・・
69
+
71
70
  ```
72
- `VM名`,`image`,`flavor`は必須項目です。
73
- `networks`について指定する場合は、`bootproto`,`ip_address`が必須です。`ip_address`は`xxx.xxx.xxx.xxx/yy`の方式を想定しており、ネットワークアドレスが指定された場合、そのサブネットで未使用のアドレスを自動で採番します。
74
- またnetworksが指定された場合は自動でVM内に`/etc/sysconfig/network-script/ifcfg-ethXXX`を作成します。
75
- ファイルの保存パスに指定が必要な場合は`path`を指定してください。
76
- `bootproto`,`ip_address`,`path`以外の値が設定されている場合は、`ifcfg-ethXXX`にそのままの値が`KEY=value`形式で出力されます。
77
- `user_data`については`nova api`にネットワーク設定を加えて引き渡すため、cloud-init記法に準拠します。
71
+ ##### Detail
72
+
73
+ | 項目名 | 説明 | 必須 | 例示 |
74
+ | -------------- | ---------------------------------------------- | ---- | ------------------------------- |
75
+ | instance_name| インスタンス名 | ○ | pyama-test001 |
76
+ | image | イメージ名 | ○ | centos-7.1_chef-12.3_puppet-3.7 |
77
+ | flavor | フレーバー名 | ○ | m1.small |
78
+ | networks | ネットワーク定義 | - | [] |
79
+ | security_group | セキュリティグループ名 | - | [default,ssh] |
80
+ | templates | `user_data`のテンプレート.`./user_datas`に配置 | - | [base.yaml,webserver.yaml] |
81
+ | user_data | cloud-init記法に準拠 | - | - |
78
82
 
83
+ ##### Networks
84
+ | 項目名 | 説明 | 必須 | 例示 |
85
+ | ------------ | ---------------- | ---- | -------------- |
86
+ | device_name | デバイス名 | ○ | eth0 |
87
+ | bootproto | 設定方式 | ○ | static or dhcp |
88
+ | ip_address | IPアドレス(CIDR) | ※ | 10.1.1.1/24 |
89
+ | path | NW設定保存パス | | default:/etc/sysconfig/network-scripts/ifcfg-[device_name] |
90
+ ※ bootproto=staticの場合必須
91
+ 上記以外の項目は設定ファイルに`KEY=value`形式で出力されます。
79
92
 
80
93
  ## Author
81
94
  * pyama86
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new("spec")
5
+ task :default => :spec
data/lib/pec.rb CHANGED
@@ -2,6 +2,7 @@ require 'fog'
2
2
  require 'ip'
3
3
  require "pec/version"
4
4
  require "pec/query"
5
+ require "pec/errors"
5
6
  require "pec/vm_director"
6
7
  require "pec/configure"
7
8
  require "pec/configure/sample"
@@ -6,12 +6,16 @@ module Pec
6
6
  desc 'init', 'create sample config'
7
7
  def init
8
8
  dirname = "user_datas"
9
- FileUtils.mkdir_p(dirname) unless FileTest.exist?(dirname)
10
-
11
- open("Pec.yaml","w") do |e|
12
- YAML.dump(Pec::Configure::Sample.pec_file, e)
13
- end unless File.exist?("Pec.yaml")
14
-
9
+ unless FileTest.exist?(dirname)
10
+ FileUtils.mkdir_p(dirname)
11
+ puts "create directry user_datas"
12
+ end
13
+ unless File.exist?("Pec.yaml")
14
+ open("Pec.yaml","w") do |e|
15
+ YAML.dump(Pec::Configure::Sample.pec_file, e)
16
+ end
17
+ puts "create configure file Pec.yaml"
18
+ end
15
19
  open("#{dirname}/web_server.yaml.sample","w") do |e|
16
20
  YAML.dump(Pec::Configure::Sample.user_data, e)
17
21
  end if FileTest.exist?(dirname)
@@ -24,21 +28,41 @@ module Pec
24
28
  config.load("Pec.yaml")
25
29
 
26
30
  director = Pec::VmDirector.new
31
+
27
32
  config.each do |host|
28
33
  next if !host_name.nil? && host.name != host_name
29
- puts "can't create server:#{host.name}" unless director.make(host)
34
+
35
+ begin
36
+ director.make(host)
37
+ rescue Pec::Errors::Error => e
38
+ puts e
39
+ puts "can't create server:#{host.name}"
40
+ rescue Excon::Errors::Error => e
41
+ JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
42
+ end
30
43
  end if config
44
+ rescue Errno::ENOENT => e
45
+ puts e
46
+ rescue Pec::Errors::Configure => e
47
+ puts "configure can't load"
31
48
  end
49
+
32
50
  option :force , type: :boolean, aliases: "-f"
33
51
  desc "destroy", "delete vm"
34
52
  def destroy(name = nil)
35
53
  config = Pec::Configure.new
36
54
  config.load("Pec.yaml")
37
-
38
55
  config.each do |host|
39
56
  next if !name.nil? && host.name != name
40
- Pec::Compute::Server.new.destroy!(host.name) if yes?("#{host.name}: Are you sure you want to destroy the '#{host.name}' VM? [y/N]") || options["force"]
57
+ begin
58
+ Pec::Compute::Server.new.destroy!(host.name) if options[:force] || yes?("#{host.name}: Are you sure you want to destroy the '#{host.name}' VM? [y/N]")
59
+ rescue Pec::Errors::Error => e
60
+ puts e
61
+ puts "can't create server:#{host.name}"
62
+ end
41
63
  end if config
64
+ rescue Errno::ENOENT => e
65
+ puts e
42
66
  end
43
67
  end
44
68
  end
@@ -6,9 +6,6 @@ module Pec
6
6
  security_groups.each do |sg_name|
7
7
  response = Fog::Compute[:openstack].add_security_group(server_id, sg_name)
8
8
  end if security_groups
9
- rescue Excon::Errors::Error => e
10
- JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
11
- false
12
9
  end
13
10
  end
14
11
  end
@@ -5,10 +5,7 @@ module Pec
5
5
  include Query
6
6
  def create(name, image_ref, flavor_ref, ports, options)
7
7
  networks = ports.map do |port|
8
- if port.used?
9
- puts "port-id:#{port.id} ip-addr:#{port.ip_address} in used"
10
- return false
11
- end
8
+ raise(Pec::Errors::Port, "port-id:#{port.id} ip-addr:#{port.ip_address} in used") if port.used?
12
9
  puts "#{name}: assingn ip #{port.ip_address}"
13
10
  { port_id: port.id }
14
11
  end if ports
@@ -22,10 +19,6 @@ module Pec
22
19
  end
23
20
 
24
21
  response.data[:body]["server"]["id"]
25
-
26
- rescue Excon::Errors::Error => e
27
- JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
28
- false
29
22
  end
30
23
 
31
24
  def exists?(server_name)
@@ -34,20 +27,12 @@ module Pec
34
27
 
35
28
  def destroy!(server_name)
36
29
  server = fetch(server_name)
37
- unless server
38
- puts "server_name:#{server_name} is not fond!"
39
- return
40
- end
41
-
30
+ raise(Pec::Errors::Host, "server_name:#{server_name} is not fond!") unless server
42
31
  response = Fog::Compute[:openstack].delete_server(server["id"]) if server
43
32
 
44
33
  if response && response[:status] == 204
45
34
  puts "server_name:#{server_name} is deleted!"
46
35
  end
47
-
48
- rescue Excon::Errors::Error => e
49
- JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
50
- false
51
36
  end
52
37
  end
53
38
  end
@@ -9,8 +9,8 @@ module Pec
9
9
  @configure ||= []
10
10
  @configure << host if host
11
11
  end
12
- rescue Psych::SyntaxError => e
13
- puts e
12
+ rescue Psych::SyntaxError,NoMethodError => e
13
+ raise(Pec::Errors::Configure, e)
14
14
  end
15
15
 
16
16
  def each
@@ -18,23 +18,19 @@ module Pec
18
18
 
19
19
  def check_require_key(name, config)
20
20
  err = %w(bootproto).find {|k| !config[1].key?(k)}
21
- return true if err.nil?
22
- puts "skip! #{name}: #{err} is required!"
23
- false
21
+ raise(Pec::Errors::Ethernet, "skip! #{name}: #{err} is required!") unless err.nil?
22
+ true
24
23
  end
25
24
 
26
25
  def check_network_key(name, config)
27
26
  net = config[1]
28
27
  case
29
28
  when (net["bootproto"] == "static" && net["ip_address"].nil?)
30
- puts "skip! #{name}: ip_address is required by bootproto static"
31
- return false
29
+ raise(Pec::Errors::Ethernet, "skip! #{name}: ip_address is required by bootproto static")
32
30
  when (!net["bootproto"] == "static" && !net["bootproto"] == "dhcp")
33
- puts "skip! #{name}: bootproto set the value dhcp or static"
34
- return false
31
+ raise(Pec::Errors::Ethernet, "skip! #{name}: bootproto set the value dhcp or static")
35
32
  when (!net["bootproto"] == "static" && !net["bootproto"] == "dhcp")
36
- puts "skip! #{name}: bootproto set the value dhcp or static"
37
- return false
33
+ raise(Pec::Errors::Ethernet, "skip! #{name}: bootproto set the value dhcp or static")
38
34
  end
39
35
  true
40
36
  end
@@ -28,9 +28,8 @@ module Pec
28
28
 
29
29
  def check_require_key(config)
30
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
31
+ raise(Pec::Errors::Host,"skip! #{config[0]}: #{err} is required!") unless err.nil?
32
+ true
34
33
  end
35
34
  end
36
35
  end
@@ -12,43 +12,36 @@ module Pec
12
12
  end
13
13
 
14
14
  def get_template(config)
15
- merge_template = {}
16
- config.templates.each do |template|
17
- if FileTest.exist?("user_datas/#{template}")
18
- merge_template.merge!(YAML.load_file("user_datas/#{template}").to_hash)
19
- else
20
- puts "template:#{temlate} is not fond!"
21
- end
15
+ config.templates.inject({}) do |merge_template, template|
16
+ raise(Pec::Errors::UserData, "template:#{template} is not fond!") unless FileTest.exist?("user_datas/#{template}")
17
+ merge_template.merge!(YAML.load_file("user_datas/#{template}").to_hash)
22
18
  end if config.templates
23
- merge_template
24
19
  end
25
20
 
26
21
  def make_port_content(config, ports)
27
22
  config.networks.map do |ether|
28
23
  port_content = {}
29
- port_content["bootproto"] = ether.bootproto
30
- port_content["name"] = ether.name unless ether.options.key?('name')
31
- port_content["name"] = ether.name unless ether.options.key?('name')
32
- port_content["device"] = ether.name unless ether.options.key?('device')
33
- port_content["type"] = 'Ethernet' unless ether.options.key?('type')
34
- port_content["onboot"] = "yes" unless ether.options.key?('onboot')
24
+ %w(name device).each do |k|
25
+ port_content[k] = ether.name unless ether.options.key?(k)
26
+ end
35
27
 
36
- _path = "/etc/sysconfig/network-scripts/ifcfg-#{ether.name}" unless ether.options.key?('path')
28
+ port_content["bootproto"] = ether.bootproto
29
+ port_content["type"] = ether.options['type'] ||'Ethernet'
30
+ port_content["onboot"] = ether.options['onboot'] || 'yes'
31
+ path = ether.options['path'] || "/etc/sysconfig/network-scripts/ifcfg-#{ether.name}"
37
32
 
38
33
  port = ports.find {|p| p.name == ether.name}
34
+ port_content["hwaddr"] = port.mac_address
39
35
 
40
- if port
41
- if ether.bootproto == "static"
42
- port_content["netmask"] = port.netmask
43
- port_content["ipaddr"] = port.ip_address
44
- end
45
- port_content["hwaddr"] = port.mac_address
36
+ if ether.bootproto == "static"
37
+ port_content["netmask"] = port.netmask
38
+ port_content["ipaddr"] = port.ip_address
46
39
  end
47
40
  port_content.merge!(ether.options)
48
41
  {
49
42
  'content' => port_content.map {|k,v| "#{k.upcase}=#{v}"}.join("\n"),
50
43
  'owner' => "root:root",
51
- 'path' => _path,
44
+ 'path' => path,
52
45
  'permissions' => "0644"
53
46
  }
54
47
  end
@@ -0,0 +1,12 @@
1
+ module Pec
2
+ module Errors
3
+ class Error < StandardError; end
4
+ class Ethernet < Error; end
5
+ class Subnet < Error; end
6
+ class Port < Error; end
7
+ class Host < Error; end
8
+ class Query < Error; end
9
+ class UserData < Error; end
10
+ class Configure < Error; end
11
+ end
12
+ end
@@ -28,7 +28,7 @@ module Pec
28
28
  when !exists?
29
29
  create(ip)
30
30
  when used?
31
- false
31
+ raise(Pec::Errors::Port, "ip:#{ip.to_addr} is used!")
32
32
  end
33
33
  end
34
34
 
@@ -89,18 +89,11 @@ module Pec
89
89
  @@use_ip_list << response.data[:body]["port"]["fixed_ips"][0]["ip_address"]
90
90
  response.data[:body]["port"]["id"]
91
91
  end
92
-
93
- rescue Excon::Errors::Error => e
94
- JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
95
- false
96
92
  end
97
93
 
98
94
  def delete(ip)
99
95
  port = fetch(ip.to_addr)
100
96
  response = Fog::Network[:openstack].delete_port(port["id"]) if port
101
- rescue Excon::Errors::Error => e
102
- JSON.parse(e.response[:body]).each { |e,m| puts "#{e}:#{m["message"]}" }
103
- false
104
97
  end
105
98
 
106
99
  def replace(ip)
@@ -3,7 +3,9 @@ module Pec
3
3
  class Subnet
4
4
  include Query
5
5
  def fetch(cidr)
6
- list.find {|p| p["cidr"] == cidr }
6
+ subnet = list.find {|p| p["cidr"] == cidr }
7
+ raise(Pec::Errors::Subnet, "cidr:#{cidr} is not fond!") unless subnet
8
+ subnet
7
9
  end
8
10
  end
9
11
  end
@@ -24,7 +24,9 @@ module Pec
24
24
  end
25
25
 
26
26
  def get_ref(name)
27
+ class_name = self.class.name.demodulize.downcase
27
28
  response = fetch(name)
29
+ raise(Pec::Errors::Query, "#{class_name}:#{name} ref is not fond!") unless response
28
30
  response["links"][0]["href"]
29
31
  end
30
32
  end
@@ -1,3 +1,3 @@
1
1
  module Pec
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -15,47 +15,28 @@ module Pec
15
15
  end
16
16
 
17
17
  ports = get_ports(config)
18
- flavor_ref = get_flavor(config.flavor)
19
- image_ref = get_image(config.image)
18
+ flavor_ref = @flavor.get_ref(config.flavor)
19
+ image_ref = @image.get_ref(config.image)
20
+ options = { "user_data" => Pec::Configure::UserData.make(config, ports) }
20
21
 
21
- return false unless flavor_ref && image_ref
22
-
23
- options = {
24
- "user_data" => Pec::Configure::UserData.make(config, ports),
25
- }
26
22
  @compute.create(config.name, image_ref, flavor_ref, ports, options)
27
23
  end
28
24
 
29
25
  def get_ports(config)
30
26
  config.networks.map do |ether|
31
- ip = IP.new(ether.ip_address)
32
- _subnet = get_subnet(ip)
33
- _port = Pec::Network::Port.new(ether.name, ip.to_addr, _subnet, get_security_group_id(config.security_group)) if _subnet
34
-
35
- unless _port.assign!(ip)
36
- puts "ip addess:#{ip.to_addr} can't create port!"
37
- return false
27
+ begin
28
+ ip = IP.new(ether.ip_address)
29
+ rescue ArgumentError => e
30
+ raise(Pec::Errors::Port, "ip:#{ether.ip_address} #{e}")
38
31
  end
39
- _port
40
- end if config.networks
41
- end
42
32
 
43
- def get_subnet(ip)
44
- _subnet = @subnet.fetch(ip.network.to_s)
45
- puts "ip addess:#{ip.to_addr} subnet not fond!" if _subnet.nil?
46
- _subnet
47
- end
48
-
49
- def get_flavor(name)
50
- flavor_ref = @flavor.get_ref(name)
51
- puts "flavor:#{name} not fond!" if flavor_ref.nil?
52
- flavor_ref
53
- end
33
+ subnet = @subnet.fetch(ip.network.to_s)
34
+ raise(Pec::Errors::Subnet, "subnet:#{ip.network.to_s} is not fond!") unless subnet
54
35
 
55
- def get_image(name)
56
- image_ref = @image.get_ref(name)
57
- puts "image:#{name} not fond!" if image_ref.nil?
58
- image_ref
36
+ port = Pec::Network::Port.new(ether.name, ip.to_addr, subnet, get_security_group_id(config.security_group))
37
+ raise(Pec::Errors::Port, "ip addess:#{ip.to_addr} can't create port!") unless port.assign!(ip)
38
+ port
39
+ end if config.networks
59
40
  end
60
41
 
61
42
  def get_security_group_id(security_groups)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - kazuhiko yamashita
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-08 00:00:00.000000000 Z
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: openstac vm booter.
14
14
  email:
@@ -20,6 +20,7 @@ executables:
20
20
  extensions: []
21
21
  extra_rdoc_files: []
22
22
  files:
23
+ - ".coveralls.yml"
23
24
  - ".gitignore"
24
25
  - ".travis.yml"
25
26
  - Gemfile
@@ -40,6 +41,7 @@ files:
40
41
  - lib/pec/configure/host.rb
41
42
  - lib/pec/configure/sample.rb
42
43
  - lib/pec/configure/user_data.rb
44
+ - lib/pec/errors.rb
43
45
  - lib/pec/network/port.rb
44
46
  - lib/pec/network/subnet.rb
45
47
  - lib/pec/query.rb
@@ -66,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
68
  version: '0'
67
69
  requirements: []
68
70
  rubyforge_project:
69
- rubygems_version: 2.4.6
71
+ rubygems_version: 2.4.7
70
72
  signing_key:
71
73
  specification_version: 4
72
74
  summary: openstack vm booter.