pec 0.5.0 → 0.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a7355209a3c35e40ac68d514cae1e0ed75e8102
4
- data.tar.gz: ea45ced7c65397076d2c7496eb5efe44ffa6d41a
3
+ metadata.gz: aee729f5850370d4c8952b4d3cd740451734d435
4
+ data.tar.gz: 03d566fbd321cdd48398e557e544eb7a99d03f3e
5
5
  SHA512:
6
- metadata.gz: 3f40e9678fbd05ffeac16fac0ca9eb1832185a38526a188149a473dee6d8e397d1250b1c081a30b687262fb02e7ebab83b02c53dcca3d9b03f7cb4f15daffdb8
7
- data.tar.gz: 57feae3668f00d475f1b1be8871294caa4fb7ac72ace25a78a9af76e57220cf1dd70dcf58e4aa7e5b5392e20db6c782cf49fd11459c664c44046697d56accc1d
6
+ metadata.gz: 92fd5ce89d06b31c5e75df19f6491650635ac63c077956f2cff1833c20bfc1565ff1be034b1213721bd943c28905fc90379f961f5b22691858fbd63421ebe69a
7
+ data.tar.gz: 956df3f42e44c7fa0e27f610728da2a7182ed5f3c91e5f87b62ca531ec06159338871325f2d35c9d4fa4c906183e931402a508af98e6df2070967c1eed450525
data/.travis.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
3
  - 2.1.6
5
4
  - 2.2.2
6
5
  addons:
data/lib/pec.rb CHANGED
@@ -5,9 +5,9 @@ require "pec/version"
5
5
  require "pec/logger"
6
6
  require "pec/configure"
7
7
  require "pec/director"
8
- require "pec/builder/server"
9
- require "pec/builder/port"
10
- require "pec/builder/user_data"
8
+ require "pec/handler"
9
+ require "pec/sample"
10
+ require "pec/init"
11
11
  require "pec/cli"
12
12
 
13
13
  module Pec
@@ -41,6 +41,19 @@ module Pec
41
41
  end
42
42
 
43
43
  def self.configure
44
+ load_config unless @_configure
44
45
  @_configure
45
46
  end
46
47
  end
48
+
49
+ class ::Hash
50
+
51
+ def deep_merge(second)
52
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
53
+ self.merge(second.to_h, &merger)
54
+ end
55
+
56
+ def deep_merge!(second)
57
+ self.merge!(deep_merge(second))
58
+ end
59
+ end
data/lib/pec/configure.rb CHANGED
@@ -9,8 +9,11 @@ module Pec
9
9
  @_config[0]
10
10
  end
11
11
 
12
+ def keys
13
+ @_config[1].keys
14
+ end
15
+
12
16
  def method_missing(method, *args)
13
- nil unless @_config[1][method.to_s]
14
17
  @_config[1][method.to_s]
15
18
  end
16
19
 
data/lib/pec/director.rb CHANGED
@@ -1,26 +1,22 @@
1
1
  module Pec
2
2
  class Director
3
3
  def self.make(host_name)
4
- Pec.load_config
5
4
  Pec.configure.each do |host|
6
5
  next if host_name && host.name != host_name
7
6
  Pec::Logger.info "make start #{host.name}"
8
-
9
7
  Pec.compute.set_tenant(host.tenant)
10
8
  Pec.neutron.set_tenant_patch(host.tenant)
11
-
12
- port_builder = Pec::Builder::Port.new
13
- server_builder = Pec::Builder::Server.new
14
- user_data_builder = Pec::Builder::UserData.new
15
-
16
- attribute = {}
17
- attribute.merge!(server_builder.build(host))
18
- attribute.merge!(port_builder.build(host))
19
9
 
20
- if user_data = user_data_builder.build(host, port_builder.user_data)
21
- attribute.merge!(user_data)
10
+ attribute = { name: host.name}
11
+ host.keys.each do |k|
12
+ Pec::Handler.constants.each do |c|
13
+ if Object.const_get("Pec::Handler::#{c}").kind == k
14
+ attribute.deep_merge!(Object.const_get("Pec::Handler::#{c}").build(host))
15
+ end
16
+ end
22
17
  end
23
18
 
19
+ attribute[:user_data] = "#cloud-config\n" + attribute[:user_data].to_yaml if attribute[:user_data]
24
20
  Pec::Logger.info "create success! #{host.name}" if Pec.compute.servers.create(attribute)
25
21
  end
26
22
 
@@ -31,7 +27,6 @@ module Pec
31
27
  end
32
28
 
33
29
  def self.destroy(host_name, options)
34
- Pec.load_config
35
30
  Pec.configure.each do |host|
36
31
  next if host_name && host.name != host_name
37
32
  Pec.compute.set_tenant(host.tenant)
@@ -46,6 +41,7 @@ module Pec
46
41
  Pec::Logger.info "#{host.name} is deleted!" if Pec.compute.servers.destroy(server.id)
47
42
  end
48
43
  end
44
+
49
45
  rescue Excon::Errors::Error => e
50
46
  excon_err_message(e)
51
47
  rescue => e
@@ -53,11 +49,9 @@ module Pec
53
49
  end
54
50
 
55
51
  def self.status(host_name)
56
- Pec.load_config
57
52
  Pec.configure.each do |host|
58
53
  next if host_name && host.name != host_name
59
- server = Pec.compute.servers.find {|s|s.name == host.name}
60
- if server
54
+ if server = Pec.compute.servers.find {|s|s.name == host.name}
61
55
  puts sprintf(" %-35s %-10s %-10s %-10s %-10s %-35s %-48s",
62
56
  host.name,
63
57
  server.state,
@@ -65,13 +59,12 @@ module Pec
65
59
  Pec.compute.flavors.get(server.flavor['id']).name,
66
60
  server.availability_zone,
67
61
  server.os_ext_srv_attr_host,
68
- server.addresses.map do |net, ethers|
69
- ethers.map do |ether|
62
+ server.addresses.map do |ethers|
63
+ ethers[1].map do |ether|
70
64
  ether["addr"]
71
65
  end
72
66
  end.flatten.join(",")
73
67
  )
74
-
75
68
  else
76
69
  puts sprintf(" %-35s %-10s",
77
70
  host.name,
@@ -0,0 +1,11 @@
1
+ module Pec
2
+ module Handler
3
+ autoload :Base, "pec/handler/base"
4
+ autoload :AvailabilityZone, "pec/handler/availability_zone"
5
+ autoload :Image, "pec/handler/image"
6
+ autoload :Flavor, "pec/handler/flavor"
7
+ autoload :Networks, "pec/handler/networks"
8
+ autoload :UserData, "pec/handler/user_data"
9
+ autoload :Templates, "pec/handler/templates"
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Pec::Handler
2
+ class AvailabilityZone < Base
3
+ self.kind = 'availability_zone'
4
+
5
+ def self.build(host)
6
+ Pec::Logger.notice "availability_zone is #{host.availability_zone}"
7
+ {
8
+ availability_zone: host.availability_zone
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Pec::Handler
2
+ class Base
3
+ class << self
4
+ attr_accessor :kind
5
+
6
+ %w(image flavor).each do |name|
7
+ define_method("fetch_#{name}", -> (host) {
8
+ unless resource = Pec.compute.send("#{name}s").find {|val|val.name == host.send(name)}
9
+ raise "not fond #{name} #{host.send(name)}"
10
+ end
11
+ resource
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Pec::Handler
2
+ class Flavor < Base
3
+ self.kind = 'image'
4
+
5
+ def self.build(host)
6
+ Pec::Logger.notice "flavor is #{host.flavor}"
7
+ {
8
+ flavor_ref: fetch_flavor(host).id,
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Pec::Handler
2
+ class Image < Base
3
+ self.kind = 'image'
4
+
5
+ def self.build(host)
6
+ Pec::Logger.notice "image is #{host.image}"
7
+ {
8
+ image_ref: fetch_image(host).id
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,114 @@
1
+ module Pec::Handler
2
+ class Networks < Base
3
+ self.kind = 'networks'
4
+ autoload :OptionBase, "pec/handler/networks/option_base"
5
+ autoload :IpAddress, "pec/handler/networks/ip_address"
6
+ autoload :AllowedAddressPairs, "pec/handler/networks/allowed_address_pairs"
7
+
8
+ class << self
9
+ NAME = 0
10
+ CONFIG = 1
11
+
12
+ def build(host)
13
+ ports = []
14
+ user_data = []
15
+
16
+ host.networks.each do |network|
17
+ validate(network)
18
+ Pec::Logger.notice "port create start : #{network[NAME]}"
19
+ port = create_port(host, network)
20
+ Pec::Logger.notice "assgin ip : #{port.fixed_ips.first["ip_address"]}"
21
+ ports << port
22
+ user_data << gen_user_data(network, port)
23
+ end
24
+ {
25
+ nics: ports.map {|port| { port_id: port.id }},
26
+ user_data: {
27
+ 'write_files' => user_data
28
+ }
29
+ }
30
+ end
31
+
32
+ def validate(network)
33
+ %w(
34
+ bootproto
35
+ ip_address
36
+ ).each do |k|
37
+ raise "network key #{k} is require" unless network[CONFIG][k]
38
+ end
39
+ end
40
+
41
+ def create_port(host, network)
42
+ attribute = gen_port_attribute(host, network)
43
+ Pec.neutron.ports.create(attribute)
44
+ end
45
+
46
+ def gen_port_attribute(host, network)
47
+ ip = IP.new(network[CONFIG]['ip_address'])
48
+ subnet = Pec.neutron.subnets.find {|s|s.cidr == ip.network.to_s}
49
+ attribute = {
50
+ name: network[NAME],
51
+ network_id: subnet.network_id
52
+ }
53
+
54
+ attribute.merge!(
55
+ security_group(host)
56
+ ) if host.security_group
57
+
58
+ network[CONFIG].keys.each do |k|
59
+ Pec::Handler::Networks.constants.each do |c|
60
+ if Object.const_get("Pec::Handler::Networks::#{c}").kind == k &&
61
+ ops = Object.const_get("Pec::Handler::Networks::#{c}").build(network)
62
+ attribute.deep_merge!(ops)
63
+ end
64
+ end
65
+ end
66
+
67
+ attribute
68
+ end
69
+
70
+ def gen_user_data(network, port)
71
+ path = network[CONFIG]['path'] || "/etc/sysconfig/network-scripts/ifcfg-#{port.name}"
72
+ {
73
+ 'content' => ifcfg_config(network, port),
74
+ 'owner' => "root:root",
75
+ 'path' => path,
76
+ 'permissions' => "0644"
77
+ }
78
+ end
79
+
80
+ def ifcfg_config(network, port)
81
+ base = {
82
+ "name" => port.name,
83
+ "device" => port.name,
84
+ "type" => 'Ethernet',
85
+ "onboot" => 'yes',
86
+ "hwaddr" => port.mac_address
87
+ }
88
+ base.merge!(
89
+ {
90
+ "netmask" => IP.new(network[CONFIG]['ip_address']).netmask.to_s,
91
+ "ipaddr" => port.fixed_ips.first['ip_address']
92
+ }
93
+ ) if network[CONFIG]['bootproto'] == "static"
94
+
95
+ # delete option column
96
+ Pec::Handler::Networks.constants.each do |c|
97
+ network[CONFIG].delete(Object.const_get("Pec::Handler::Networks::#{c}").kind)
98
+ end
99
+
100
+ base.merge!(
101
+ network[CONFIG]
102
+ )
103
+ base.map {|k,v| "#{k.upcase}=#{v}"}.join("\n")
104
+ end
105
+
106
+ def security_group(host)
107
+ ids = host.security_group.map do |name|
108
+ Pec.neutron.security_groups.find {|sg| sg.name == name}.id
109
+ end
110
+ { security_groups: ids }
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,17 @@
1
+ module Pec::Handler
2
+ class Networks
3
+ class AllowedAddressPairs< OptionBase
4
+ self.kind = 'allowed_address_pairs'
5
+ class << self
6
+ def build(network)
7
+ if network[1]['allowed_address_pairs']
8
+ pairs = network[1]['allowed_address_pairs'].map do |pair|
9
+ { ip_address: pair['ip_address'] }
10
+ end
11
+ { allowed_address_pairs: pairs }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Pec::Handler
2
+ class Networks
3
+ class IpAddress < OptionBase
4
+ self.kind = 'ip_address'
5
+ class << self
6
+ def build(network)
7
+ ip = IP.new(network[1]['ip_address'])
8
+ subnet = Pec.neutron.subnets.find {|s|s.cidr == ip.network.to_s}
9
+
10
+ if ip.to_s != subnet.cidr
11
+ {
12
+ fixed_ips: [
13
+ { subnet_id: subnet.id, ip_address: ip.to_addr}
14
+ ]
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module Pec::Handler
2
+ class Networks
3
+ class OptionBase
4
+ class << self
5
+ attr_accessor :kind
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Pec::Handler
2
+ class Templates < Base
3
+ self.kind = 'templates'
4
+ class << self
5
+ def build(host)
6
+ { user_data: load_template(host) }
7
+ end
8
+
9
+ def load_template(host)
10
+ host.templates.inject({}) do |merge_template, template|
11
+ template.to_s.concat('.yaml') unless template.to_s.match(/.*\.yaml/)
12
+ Pec::Logger.notice "load template #{template}"
13
+
14
+ raise "#{template} not fond!" unless FileTest.exist?("user_data/#{template}")
15
+ merge_template.deep_merge!(YAML.load_file("user_data/#{template}").to_hash)
16
+ end if host.templates
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Pec::Handler
2
+ class UserData < Base
3
+ self.kind = 'user_data'
4
+ class << self
5
+ def build(host)
6
+ user_data = host.user_data || {}
7
+ user_data['fqdn'] = host.name if host.user_data && !host.user_data['fqdn']
8
+ { user_data: user_data }
9
+ end
10
+ end
11
+ end
12
+ end
13
+
data/lib/pec/sample.rb ADDED
@@ -0,0 +1,55 @@
1
+ module Pec
2
+ class Configure
3
+ class Sample
4
+ class << self
5
+ def pec_file
6
+ {
7
+ "your_sever_name" => {
8
+ "tenant" => "your_tenant",
9
+ "image" => "centos-7",
10
+ "flavor" => "m1.small",
11
+ "networks" => {
12
+ "eth0" => {
13
+ "bootproto" => "static",
14
+ "ip_address" => "10.0.0.0/24",
15
+ "gateway" => "10.0.0.254",
16
+ "dns1" => "10.0.0.10"
17
+ },
18
+ "eth1" => {
19
+ "bootproto" => "static",
20
+ "ip_address" => "20.0.0.11/24",
21
+ "gateway" => "20.0.0.254",
22
+ "dns1" => "20.0.0.10"
23
+ }
24
+ },
25
+ "security_group" => [
26
+ "default",
27
+ "www from any"
28
+ ],
29
+ "templates" => [
30
+ "web_server.yaml"
31
+ ],
32
+ "user_data" => {
33
+ "hostname" => "pec",
34
+ "fqdn" => "pec.pyama.com"
35
+ }
36
+ }
37
+ }
38
+ end
39
+ def user_data
40
+ {
41
+ "hostname" => "pec",
42
+ "fqdn" => "pec.pyama.com",
43
+ "users" => [
44
+ {
45
+ "name" => "centos",
46
+ "groups" => "sudo",
47
+ "shell" => "/bin/sh"
48
+ }
49
+ ]
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/pec/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pec
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
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.5.0
4
+ version: 0.5.1
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-08-23 00:00:00.000000000 Z
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -143,15 +143,23 @@ files:
143
143
  - bin/setup
144
144
  - exe/pec
145
145
  - lib/pec.rb
146
- - lib/pec/builder/port.rb
147
- - lib/pec/builder/server.rb
148
- - lib/pec/builder/user_data.rb
149
146
  - lib/pec/cli.rb
150
147
  - lib/pec/configure.rb
151
148
  - lib/pec/director.rb
152
- - lib/pec/errors.rb
149
+ - lib/pec/handler.rb
150
+ - lib/pec/handler/availability_zone.rb
151
+ - lib/pec/handler/base.rb
152
+ - lib/pec/handler/flavor.rb
153
+ - lib/pec/handler/image.rb
154
+ - lib/pec/handler/networks.rb
155
+ - lib/pec/handler/networks/allowed_address_pairs.rb
156
+ - lib/pec/handler/networks/ip_address.rb
157
+ - lib/pec/handler/networks/option_base.rb
158
+ - lib/pec/handler/templates.rb
159
+ - lib/pec/handler/user_data.rb
153
160
  - lib/pec/init.rb
154
161
  - lib/pec/logger.rb
162
+ - lib/pec/sample.rb
155
163
  - lib/pec/version.rb
156
164
  - pec.gemspec
157
165
  homepage: http://ten-snapon.com
@@ -1,120 +0,0 @@
1
- module Pec
2
- module Builder
3
- class Port
4
- attr_reader :user_data
5
- def build(host)
6
- ports = []
7
- @user_data = []
8
-
9
- host.networks.each do |network|
10
- validate(network)
11
- Pec::Logger.notice "port create start : #{network[0]}"
12
- port = create_port(host, network)
13
- Pec::Logger.notice "assgin ip : #{port.fixed_ips.first["ip_address"]}"
14
- ports << port
15
- @user_data << gen_user_data(network, port)
16
- end
17
- {
18
- nics: ports.map {|port| { port_id: port.id }}
19
- }
20
- end
21
-
22
- def validate(network)
23
- %w(
24
- bootproto
25
- ip_address
26
- ).each do |k|
27
- raise "network key #{k} is require" unless network[1][k]
28
- end
29
- end
30
-
31
- def create_port(host, network)
32
- ip = IP.new(network[1]['ip_address'])
33
- subnet = Pec.neutron.subnets.find {|s|s.cidr == ip.network.to_s}
34
- attribute = gen_port_attribute(host, network, subnet, ip)
35
- Pec.neutron.ports.create(attribute)
36
- end
37
-
38
- def gen_port_attribute(host, network, subnet, ip)
39
- attribute = {
40
- name: network[0],
41
- network_id: subnet.network_id
42
- }
43
-
44
- attribute.merge!(
45
- fixed_ip(subnet, ip)
46
- ) if ip.to_s != subnet.cidr
47
-
48
- attribute.merge!(
49
- security_group(host)
50
- ) if host.security_group
51
-
52
- attribute.merge!(
53
- allowed_address_pairs(network)
54
- ) if network[1]['allowed_address_pairs']
55
- attribute
56
- end
57
-
58
- def gen_user_data(network, port)
59
- path = network[1]['path'] || "/etc/sysconfig/network-scripts/ifcfg-#{port.name}"
60
- {
61
- 'content' => ifcfg_config(network, port),
62
- 'owner' => "root:root",
63
- 'path' => path,
64
- 'permissions' => "0644"
65
- }
66
- end
67
-
68
- def ifcfg_config(network, port)
69
- base = {
70
- "name" => port.name,
71
- "device" => port.name,
72
- "type" => 'Ethernet',
73
- "onboot" => 'yes',
74
- "hwaddr" => port.mac_address
75
- }
76
-
77
- base.merge!(
78
- {
79
- "netmask" => IP.new(network[1]['ip_address']).netmask.to_s,
80
- "ipaddr" => port.fixed_ips.first['ip_address'].split("/").first
81
- }
82
- ) if network[1]['bootproto'] == "static"
83
-
84
- # delete options
85
- %w(allowed_address_pairs ip_address).each {|name| network[1].delete(name)}
86
-
87
- base.merge!(
88
- network[1]
89
- )
90
-
91
- base.map {|k,v| "#{k.upcase}=#{v}"}.join("\n")
92
- end
93
-
94
- #
95
- # after port options
96
- #
97
- def fixed_ip(subnet, ip)
98
- {
99
- fixed_ips: [
100
- { subnet_id: subnet.id, ip_address: ip.to_addr}
101
- ]
102
- }
103
- end
104
-
105
- def security_group(host)
106
- ids = host.security_group.map do |name|
107
- Pec.neutron.security_groups.find {|sg| sg.name == name}.id
108
- end
109
- { security_groups: ids }
110
- end
111
-
112
- def allowed_address_pairs(network)
113
- pairs = network[1]['allowed_address_pairs'].map do |pair|
114
- { ip_address: pair['ip_address'] }
115
- end
116
- { allowed_address_pairs: pairs }
117
- end
118
- end
119
- end
120
- end
@@ -1,28 +0,0 @@
1
- module Pec
2
- module Builder
3
- class Server
4
- def build(host)
5
- Pec::Logger.notice "flavor is #{host.flavor}"
6
- Pec::Logger.notice "image is #{host.image}"
7
- hash = {
8
- name: host.name,
9
- flavor_ref: fetch_flavor(host).id,
10
- image_ref: fetch_image(host).id
11
- }
12
- hash[:availability_zone] = host.availability_zone if host.availability_zone
13
- hash
14
- end
15
-
16
- def self.resource(name)
17
- define_method("fetch_#{name}", -> (host) {
18
- r = Pec.compute.send("#{name}s").find {|val|val.name == host.send(name)}
19
- raise "not fond #{name} #{host.send(name)}" unless r
20
- r
21
- })
22
- end
23
-
24
- resource 'flavor'
25
- resource 'image'
26
- end
27
- end
28
- end
@@ -1,39 +0,0 @@
1
- module Pec
2
- module Builder
3
- class UserData
4
- def build(host, port_user_data)
5
- user_data = default(host)
6
- user_data["write_files"] = port_user_data if port_user_data
7
- if template = load_template(host)
8
- user_data.deep_merge!(template)
9
- end
10
- { user_data: "#cloud-config\n" + user_data.to_yaml }
11
- end
12
-
13
- def load_template(host)
14
- host.templates.inject({}) do |merge_template, template|
15
- template.to_s.concat('.yaml') unless template.to_s.match(/.*\.yaml/)
16
- raise "#{template} not fond!" unless FileTest.exist?("user_data/#{template}")
17
- merge_template.deep_merge!(YAML.load_file("user_data/#{template}").to_hash)
18
- end if host.templates
19
- end
20
-
21
- def default(host)
22
- _def = host.user_data || {}
23
- _def['fqdn'] = host.name if host.user_data && !host.user_data['fqdn']
24
- _def
25
- end
26
- end
27
- end
28
- end
29
-
30
- class ::Hash
31
- def deep_merge(second)
32
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
33
- self.merge(second.to_h, &merger)
34
- end
35
- def deep_merge!(second)
36
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
37
- self.merge!(second.to_h, &merger)
38
- end
39
- end
data/lib/pec/errors.rb DELETED
@@ -1,14 +0,0 @@
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
- class SecurityGroup < Error; end
12
- class Resource < Error; end
13
- end
14
- end