gce-host 0.3.4 → 0.4.0

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: f473115294b06f624354470a0b77ff09e5275f28
4
- data.tar.gz: f1fdc1d27677d158fa9fa5952bc35a29e91d163e
3
+ metadata.gz: f1b7d2580b2e20e9f49b95b23fd29520075b2ae8
4
+ data.tar.gz: 17c9de1adc6e4a5f456e3d75b8c08db4a06ba01d
5
5
  SHA512:
6
- metadata.gz: 0cec3a2009fa765ec7e72ca048dcead0d88bb7459a6e765b67be057d4178e2d83ef6b43f3f973e7496aac61c81e8313421d5d836fa46b7d3fb595d24334b4800
7
- data.tar.gz: 6a69cf30ef0cef6f6326b0858a30dc639e5106781a78640742b4acfb29bf92751d1f39e7fad065a724b69cfdb9b5861a904084eb7e2bb0cd5a79b599690d7893
6
+ metadata.gz: 774f8e55112193adfdce84863dc93e34a7cf1d71aa78a60be78c003a4d59259fa07dee525d1b81489e36c769795d574985f49772243f72f3d822159b38a402da
7
+ data.tar.gz: f1dd7e96959f7d906e71f16da61a13188013fcf39d9aa5a3d3604aa4a498c4240ace304f33193ec84c7198087180d2c7fafddc17b8069eae746e422aa72fd45b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.4.0 (2016/12/02)
2
+
3
+ Enhancements:
4
+
5
+ * Support role levels more than 3 by ROLE_MAX_DEPTH configuration
6
+
1
7
  # 0.3.4 (2016/11/28)
2
8
 
3
9
  Enhancements
data/README.md CHANGED
@@ -17,7 +17,7 @@ You can manage roles of a host, and search hosts having a specified role using t
17
17
 
18
18
  ## Configuration
19
19
 
20
- You can write a configuration file located at `/etc/sysconfig/gce-host` for CentOS, or `/etc/default/gce-host` for Ubuntu (You can configure this path by `GCE_HOST_CONFIG_FILE` environment variable), or as environment variables:
20
+ You can write a configuration file located at `/etc/sysconfig/gce-host` or `/etc/default/gce-host` (You can configure this path by `GCE_HOST_CONFIG_FILE` environment variable), or as environment variables:
21
21
 
22
22
  GOOGLE API parameters:
23
23
 
@@ -35,6 +35,7 @@ gce-host parameters:
35
35
  * **OPTIONAL_STRING_KEYS (optional)**: You may add optional non-array metadata keys. You can specify multiple keys like `service,status`.
36
36
  * **OPTIONAL_ARRAY_KEYS (optional)**: You may add optional array metadata keys. Array allows multiple values delimited by `ARRAY_VALUE_DELIMITER` (default: `,`)
37
37
  * **ARRAY_VALUE_DELIMITER (optional)**: A delimiter to express array. Default is `,`
38
+ * **ROLE_MAX_DEPTH (optional)**: The maximum depth of levels of roles. Default is 3.
38
39
  * **LOG_LEVEL (optional)**: Log level such as `info`, `debug`, `error`. The default is `info`.
39
40
 
40
41
  See [example.conf](./example/example.conf)
@@ -120,9 +121,9 @@ $ bin/gce-host --help
120
121
  Usage: gce-host [options]
121
122
  --hostname one,two,three name or private_dns_name
122
123
  -r, --role one,two,three role
123
- --r1, --role1 one,two,three role1, the 1st part of role delimited by :
124
- --r2, --role2 one,two,three role2, the 2st part of role delimited by :
125
- --r3, --role3 one,two,three role3, the 3st part of role delimited by :
124
+ --r1, --role1 one,two,three role1, 1th part of role delimited by :
125
+ --r2, --role2 one,two,three role2, 2th part of role delimited by :
126
+ --r3, --role3 one,two,three role3, 3th part of role delimited by :
126
127
  --state one,two,three filter with instance state (default: running)
127
128
  -a, --all list all hosts (remove default filter)
128
129
  --private-ip, --ip show private ip address instead of hostname
data/example/example.conf CHANGED
@@ -5,5 +5,6 @@ ROLE_VALUE_DELIMITER=:
5
5
  OPTIONAL_STRING_KEYS=service,status
6
6
  OPTIONAL_ARRAY_KEYS=tags
7
7
  ARRAY_VALUE_DELIMITER=,
8
+ ROLE_MAX_DEPTH=5
8
9
  LOG_LEVEL=info
9
10
  STATUS=state
data/lib/gce/host/cli.rb CHANGED
@@ -31,15 +31,11 @@ class GCE
31
31
  op.on('-r', '--role one,two,three', Array, "role") {|v|
32
32
  opts[:role] = v
33
33
  }
34
- op.on('--r1', '--role1 one,two,three', Array, "role1, the 1st part of role delimited by #{Config.role_value_delimiter}") {|v|
35
- opts[:role1] = v
36
- }
37
- op.on('--r2', '--role2 one,two,three', Array, "role2, the 2st part of role delimited by #{Config.role_value_delimiter}") {|v|
38
- opts[:role2] = v
39
- }
40
- op.on('--r3', '--role3 one,two,three', Array, "role3, the 3st part of role delimited by #{Config.role_value_delimiter}") {|v|
41
- opts[:role3] = v
42
- }
34
+ 1.upto(Config.role_max_depth).each do |i|
35
+ op.on("--r#{i}", "--role#{i} one,two,three", Array, "role#{i}, #{i}th part of role delimited by #{Config.role_value_delimiter}") {|v|
36
+ opts["role#{i}".to_sym] = v
37
+ }
38
+ end
43
39
  op.on('--instance-id one,two,three', Array, "instance_id") {|v|
44
40
  opts[:instance_id] = v
45
41
  }
@@ -52,9 +48,12 @@ class GCE
52
48
  }
53
49
  end
54
50
  op.on('-a', '--all', "list all hosts (remove default filter)") {|v|
55
- [:hostname, :role, :role1, :role2, :role3, :instance_id, Config.status.to_sym].each do |key|
51
+ [:hostname, :role, :instance_id, Config.status.to_sym].each do |key|
56
52
  opts.delete(key)
57
53
  end
54
+ 1.upto(Config.role_max_depth).each do |i|
55
+ opts.delete("role#{i}".to_sym)
56
+ end
58
57
  Config.optional_options.keys.each do |opt|
59
58
  opts.delete(opt.to_sym)
60
59
  end
@@ -4,6 +4,8 @@ require 'inifile'
4
4
 
5
5
  class GCE
6
6
  class Host
7
+ class ConfigError < StandardError; end
8
+
7
9
  class Config
8
10
  def self.configure(params)
9
11
  params.each do |key, val|
@@ -93,6 +95,10 @@ class GCE
93
95
  @status ||= ENV['STATUS'] || config.fetch('STATUS', 'status')
94
96
  end
95
97
 
98
+ def self.role_max_depth
99
+ @role_max_depth ||= Integer(ENV['ROLE_MAX_DEPTH'] || config.fetch('ROLE_MAX_DEPTH', 3))
100
+ end
101
+
96
102
  # private
97
103
 
98
104
  def self.optional_array_options
@@ -175,14 +175,14 @@ class GCE
175
175
  def role_match?(condition)
176
176
  # usage is an alias of role
177
177
  if role = (condition[:role] || condition[:usage])
178
- role1, role2, role3 = role.first.split(':')
178
+ parts = role.first.split(Config.role_value_delimiter, Config.role_max_depth)
179
179
  else
180
- role1 = (condition[:role1] || condition[:usage1] || []).first
181
- role2 = (condition[:role2] || condition[:usage2] || []).first
182
- role3 = (condition[:role3] || condition[:usage3] || []).first
180
+ parts = 1.upto(Config.role_max_depth).map do |i|
181
+ (condition["role#{i}".to_sym] || condition["usage#{i}".to_sym] || []).first
182
+ end
183
183
  end
184
- if role1
185
- return false unless roles.find {|role| role.match?(role1, role2, role3) }
184
+ if parts.first
185
+ return false unless roles.find {|role| role.match?(*parts) }
186
186
  end
187
187
  true
188
188
  end
@@ -195,7 +195,10 @@ class GCE
195
195
  end
196
196
 
197
197
  def instance_match?(condition)
198
- condition = HashUtil.except(condition, :role, :role1, :role2, :role3, :usage, :usage1, :usage2, :usage3, Config.status.to_sym)
198
+ excepts = [:role, :usage, Config.status.to_sym]
199
+ 1.upto(Config.role_max_depth).each {|i| excepts << "role#{i}".to_sym }
200
+ 1.upto(Config.role_max_depth).each {|i| excepts << "usage#{i}".to_sym }
201
+ condition = HashUtil.except(condition, *excepts)
199
202
  condition.each do |key, values|
200
203
  v = instance_variable_recursive_get(key)
201
204
  if v.is_a?(Array)
@@ -2,47 +2,68 @@ class GCE
2
2
  class Host
3
3
  # Represents each role
4
4
  class RoleData
5
- attr_reader :role1, :role2, :role3
6
-
7
- def initialize(role1, role2 = nil, role3 = nil)
8
- @role1 = role1
9
- @role2 = role2
10
- @role3 = role3
5
+ # Initialize role data with role parts
6
+ #
7
+ # RoleData.new('admin', 'jenkins', 'slave')
8
+ #
9
+ # @param [Array] role_parts such as ['admin', 'jenkins', 'slave']
10
+ def initialize(*role_parts)
11
+ @role_parts = role_parts
11
12
  end
12
13
 
14
+ # Create a role data with role delimiter by Config.role_value_delimiter
15
+ #
16
+ # RoleData.build('admin:jenkins:slave')
17
+ #
18
+ # @param [String] role such as "admin:jenkins:slave"
13
19
  def self.build(role)
14
- role1, role2, role3 = role.split(Config.role_value_delimiter, 3)
15
- new(role1, role2, role3)
20
+ role_parts = role.split(Config.role_value_delimiter, Config.role_max_depth)
21
+ new(*role_parts)
16
22
  end
17
23
 
18
24
  # @return [String] something like "admin:jenkins:slave"
19
25
  def role
20
- @role ||= [role1, role2, role3].compact.reject(&:empty?).join(Config.role_value_delimiter)
26
+ @role ||= @role_parts.compact.reject(&:empty?).join(Config.role_value_delimiter)
21
27
  end
22
28
  alias :to_s :role
23
29
 
30
+ 1.upto(Config.role_max_depth).each do |i|
31
+ define_method("role#{i}") do
32
+ @role_parts[i-1]
33
+ end
34
+ end
35
+
24
36
  # @return [Array] something like ["admin", "admin:jenkins", "admin:jenkins:slave"]
25
37
  def uppers
26
- uppers = [RoleData.new(role1)]
27
- uppers << RoleData.new(role1, role2) if role2 and !role2.empty?
28
- uppers << RoleData.new(role1, role2, role3) if role3 and !role3.empty?
29
- uppers
38
+ role_parts = @role_parts.dup
39
+ upper_role_parts = []
40
+ upper_role_parts << [role_parts.shift]
41
+ role_parts.each do |role_part|
42
+ break if role_part.nil? or role_part.empty?
43
+ upper_role_parts << [*(upper_role_parts.last), role_part]
44
+ end
45
+ upper_role_parts.map {|role_parts| RoleData.new(*role_parts) }
30
46
  end
31
47
 
32
- def match?(role1, role2 = nil, role3 = nil)
33
- if role3
34
- role1 == self.role1 and role2 == self.role2 and role3 == self.role3
35
- elsif role2
36
- role1 == self.role1 and role2 == self.role2
37
- else
38
- role1 == self.role1
48
+ # Check whether given role parts matches with this role data object
49
+ #
50
+ # RoleData.new('admin', 'jenkins', 'slave').match?('admin') #=> true
51
+ # RoleData.new('admin', 'jenkins', 'slave').match?('admin', 'jenkins') #=> true
52
+ # RoleData.new('admin', 'jenkins', 'slave').match?('admin', 'jenkins', 'slave') #=> true
53
+ # RoleData.new('admin', 'jenkins', 'slave').match?('admin', 'jenkins', 'master') #=> false
54
+ #
55
+ # @param [Array] role_parts such as ["admin", "jenkins", "slave"]
56
+ def match?(*role_parts)
57
+ (Config.role_max_depth-1).downto(0).each do |i|
58
+ next unless role_parts[i]
59
+ return @role_parts[0..i] == role_parts[0..i]
39
60
  end
40
61
  end
41
62
 
42
63
  # Equality
43
64
  #
44
- # Role::Data.new('admin') == Role::Data.new('admin') #=> true
45
- # Role::Data.new('admin', 'jenkin') == "admin:jenkins" #=> true
65
+ # RoleData.new('admin') == Role::Data.new('admin') #=> true
66
+ # RoleData.new('admin', 'jenkin') == "admin:jenkins" #=> true
46
67
  #
47
68
  # @param [Object] other
48
69
  def ==(other)
@@ -1,5 +1,5 @@
1
1
  class GCE
2
2
  class Host
3
- VERSION = '0.3.4'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
data/spec/host_spec.rb CHANGED
@@ -4,13 +4,13 @@ shared_examples_for 'host' do
4
4
  it 'should respond_to' do
5
5
  [ :hostname,
6
6
  :roles,
7
- :zone,
8
7
  GCE::Host::Config.status.to_sym,
9
8
  :service,
10
9
  :status,
11
10
  :tags,
11
+ :zone,
12
12
  :instance,
13
- :instance_id,
13
+ :machine_type,
14
14
  :private_ip_address,
15
15
  :private_ip_addresses,
16
16
  :public_ip_address,
@@ -47,11 +47,11 @@ describe GCE::Host do
47
47
  expect(subject.keys).to eq([
48
48
  'hostname',
49
49
  'roles',
50
- 'zone',
51
50
  'service',
52
51
  'status',
53
52
  'tags',
54
- 'instance_id',
53
+ 'zone',
54
+ 'machine_type',
55
55
  'private_ip_address',
56
56
  'public_ip_address',
57
57
  'creation_timestamp',
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe GCE::Host::RoleData do
4
+ describe 'initialize' do
5
+ let(:subject) { GCE::Host::RoleData.new('web', 'test') }
6
+ it do
7
+ expect(subject.role1).to eq('web')
8
+ expect(subject.role2).to eq('test')
9
+ expect(subject.role3).to be_nil
10
+ end
11
+ end
12
+
13
+ describe '#build' do
14
+ let(:subject) { GCE::Host::RoleData.build('web:test') }
15
+ it do
16
+ expect(subject.role1).to eq('web')
17
+ expect(subject.role2).to eq('test')
18
+ expect(subject.role3).to be_nil
19
+ end
20
+ end
21
+
22
+ describe '#uppers' do
23
+ let(:subject) { GCE::Host::RoleData.build('web:test').uppers }
24
+ it do
25
+ expect(subject[0]).to eq('web')
26
+ expect(subject[1]).to eq('web:test')
27
+ expect(subject[2]).to be_nil
28
+ end
29
+ end
30
+
31
+ describe '#match?' do
32
+ let(:subject) { GCE::Host::RoleData.build('web:test') }
33
+ it do
34
+ expect(subject.match?('web')).to be_truthy
35
+ expect(subject.match?('web', 'test')).to be_truthy
36
+ expect(subject.match?('web', 'test', 'wrong')).to be_falsey
37
+ expect(subject.match?('web', 'wrong')).to be_falsey
38
+ end
39
+ end
40
+ end
data/terraform.tf CHANGED
@@ -5,7 +5,7 @@ provider "google" {
5
5
 
6
6
  resource "google_compute_instance" "gce-host-web" {
7
7
  name = "gce-host-web"
8
- machine_type = "n1-standard-1"
8
+ machine_type = "f1-micro"
9
9
  zone = "asia-northeast1-a"
10
10
 
11
11
  disk {
@@ -20,7 +20,7 @@ resource "google_compute_instance" "gce-host-web" {
20
20
  }
21
21
 
22
22
  metadata {
23
- roles = "foo,web:test"
23
+ roles = "foo,web:test:foo:bar:baz"
24
24
  service = "gce-host"
25
25
  status = "reserve"
26
26
  tags = "standby"
@@ -29,7 +29,7 @@ resource "google_compute_instance" "gce-host-web" {
29
29
 
30
30
  resource "google_compute_instance" "gce-host-db" {
31
31
  name = "gce-host-db"
32
- machine_type = "n1-standard-1"
32
+ machine_type = "f1-micro"
33
33
  zone = "asia-northeast1-a"
34
34
 
35
35
  disk {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gce-host
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi Seo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-28 00:00:00.000000000 Z
11
+ date: 2016-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-api-client
@@ -207,6 +207,7 @@ files:
207
207
  - lib/gce/host/version.rb
208
208
  - spec/gce_client_spec.rb
209
209
  - spec/host_spec.rb
210
+ - spec/role_data_spec.rb
210
211
  - spec/spec_helper.rb
211
212
  - terraform.tf
212
213
  homepage: https://github.com/sonots/gce-host
@@ -236,5 +237,6 @@ summary: Search hosts on GCP GCE
236
237
  test_files:
237
238
  - spec/gce_client_spec.rb
238
239
  - spec/host_spec.rb
240
+ - spec/role_data_spec.rb
239
241
  - spec/spec_helper.rb
240
242
  has_rdoc: