kakine 0.1.0 → 0.2.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: 4768538b225d648ebf64a3eb52c7a2841cb14334
4
- data.tar.gz: 5361d5d1eb968a8d238910ff5995fb4ee3b53592
3
+ metadata.gz: d3f0de2336304ed3476ccfc1b63e2bdc01a9c1cd
4
+ data.tar.gz: c1b97adbc29b5a659b1fb38b79f04dcb596a1f53
5
5
  SHA512:
6
- metadata.gz: 5b8b3bc37780557a3c8fe2edd9209aa3f7f36e5de23bd0135f68aff7b541401609e4f77f70c04a3d0a6c803c4403c9d323be2e6d04bd2ed83ca5a620f4573cec
7
- data.tar.gz: 5f8b2b5c7389bd4faea0752ff304dada6e433255d5dee7d926c7ec15df4d8281edab36b65597245e36f1157324caa7743c487354aa5ef5d13b4485de3b39bb88
6
+ metadata.gz: c402eeb05b5d24368f1b66694965fa8fac9116a8354c11a69a33c5bc64695f9d107ed63072f523a1da22d9520bf86eed35bedff78e1811da249ae91b5ccd1c11
7
+ data.tar.gz: a2c41d220786673210a397f27d049f7d52c6ec5ae5aa623361eb08fd62d8634d7d70350d3a303f931ff2799657d9c1295dc28df9432d065ec9ed61ed9ae2fbde
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Kakine
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/hsbt/kaname.png)](https://travis-ci.org/hsbt/kaname)
3
+ [![Build Status](https://secure.travis-ci.org/hsbt/kakine.png)](https://travis-ci.org/hsbt/kakine)
4
4
 
5
5
  Kakine(垣根) is configuration management tool of Security Group on OpenStack.
6
6
 
@@ -26,19 +26,22 @@ You can define Security Group configuration for OpenStack via YAML format. Like
26
26
 
27
27
  ```yaml
28
28
  app:
29
- - direction: ingress
30
- protocol: tcp
31
- port: 443
32
- remote_ip: 0.0.0.0/0
33
- - direction: ingress
34
- protocol: tcp
35
- port: 80
36
- remote_ip: 0.0.0.0/0
29
+ rules:
30
+ - direction: ingress
31
+ protocol: tcp
32
+ port: 443
33
+ remote_ip: 0.0.0.0/0
34
+ - direction: ingress
35
+ protocol: tcp
36
+ port: 80
37
+ remote_ip: 0.0.0.0/0
38
+ description: app rules
37
39
  rails:
38
- - direction: ingress
39
- protocol: tcp
40
- port: 3000
41
- remote_ip: 0.0.0.0/0
40
+ rules:
41
+ - direction: ingress
42
+ protocol: tcp
43
+ port: 3000
44
+ remote_ip: 0.0.0.0/0
42
45
  ```
43
46
 
44
47
  You need to put fog configuration to home directory.
@@ -55,9 +58,9 @@ default:
55
58
  run following command.
56
59
 
57
60
  ```sh
58
- $ kakine show tenant_name # show Security Group of tenant_name
59
- $ kaname apply tenant_name --dryrun # You can see all of invoke commands(dryrun)
60
- $ kaname apply tenant_name # apply configuration into OpenStack
61
+ $ kakine show -t tenant_name # show Security Group of tenant_name
62
+ $ kaname apply -t tenant_name --dryrun # You can see all of invoke commands(dryrun)
63
+ $ kaname apply -t tenant_name # apply configuration into OpenStack
61
64
  ```
62
65
 
63
66
  You can create or change Security Group on targeting tenant.
@@ -65,7 +68,7 @@ You can create or change Security Group on targeting tenant.
65
68
  If you need to initialize your Security Gruop, you can get it via following command:
66
69
 
67
70
  ```sh
68
- $ kaname show tenant_name > tenant_name.yaml
71
+ $ kaname show -t tenant_name > tenant_name.yaml
69
72
  ```
70
73
 
71
74
  ## Development
@@ -1,7 +1,12 @@
1
1
  require "kakine/version"
2
2
  require 'kakine/cli'
3
+ require 'kakine/cli/operation'
3
4
  require 'kakine/adapter'
4
5
  require 'kakine/resource'
6
+ require 'kakine/hash_sort'
7
+ require 'kakine/security_group'
8
+ require 'kakine/diff_parser'
5
9
 
6
10
  module Kakine
7
11
  end
12
+
@@ -5,6 +5,7 @@ require 'hashdiff'
5
5
 
6
6
  module Kakine
7
7
  class CLI < Thor
8
+
8
9
  option :tenant, type: :string, aliases: '-t'
9
10
  desc 'show', 'show Security Groups specified tenant'
10
11
  def show
@@ -22,49 +23,57 @@ module Kakine
22
23
  Kakine::Adapter::Real.new
23
24
  end
24
25
 
26
+ operation = Kakine::CLI::Operation.new
27
+ operation.set_adapter(adapter)
28
+
25
29
  filename = options[:filename] ? options[:filename] : "#{options[:tenant]}.yaml"
26
- diffs = HashDiff.diff(Kakine::Resource.security_groups_hash(options[:tenant]), Kakine::Resource.yaml(filename))
30
+
31
+ security_groups = []
32
+ delay_create = []
33
+
34
+ diffs = HashDiff.diff(
35
+ Kakine::Resource.security_groups_hash(options[:tenant]),
36
+ Kakine::Resource.yaml(filename)
37
+ )
27
38
 
28
39
  diffs.each do |diff|
29
- sg_name, rule_modification = *diff[1].scan(/^([\w-]+)(\[\d\])?/)[0]
40
+ security_groups << Kakine::SecurityGroup.new(options[:tenant], diff)
41
+ end
30
42
 
31
- if rule_modification # foo[2]
32
- security_group = Kakine::Resource.security_group(options[:tenant], sg_name)
33
- if diff[2]["remote_group"]
34
- remote_security_group = Kakine::Resource.security_group(options[:tenant], diff[2].delete("remote_group"))
35
- diff[2]["remote_group_id"] = remote_security_group.id
36
- end
37
- case diff[0]
38
- when "+"
39
- diff[2].merge!({"ethertype" => "IPv4", "tenant_id" => Kakine::Resource.tenant(options[:tenant]).id})
40
- adapter.create_rule(security_group.id, diff[2]["direction"], diff[2])
41
- when "-"
42
- security_group_rule = Kakine::Resource.security_group_rule(security_group, diff[2])
43
- adapter.delete_rule(security_group_rule.id)
43
+ security_groups.each do |sg|
44
+ if sg.update_rule? # foo[2]
45
+ case
46
+ when sg.add?
47
+ operation.create_security_rule(sg)
48
+ when sg.delete?
49
+ operation.delete_security_rule(sg)
50
+ when sg.update_attr?
51
+ pre_sg = sg.get_prev_instance
52
+ operation.delete_security_rule(pre_sg)
53
+ delay_create << sg # avoid duplication entry
44
54
  else
45
55
  raise
46
56
  end
47
57
  else # foo
48
- case diff[0]
49
- when "+"
50
- attributes = {name: sg_name, description: "", tenant_id: Kakine::Resource.tenant(options[:tenant]).id}
51
- security_group_id = adapter.create_security_group(attributes)
52
- diff[2].each do |rule|
53
- rule.merge!({"ethertype" => "IPv4", "tenant_id" => Kakine::Resource.tenant(options[:tenant]).id})
54
- if rule["remote_group"]
55
- remote_security_group = Kakine::Resource.security_group(options[:tenant], rule.delete("remote_group"))
56
- rule["remote_group_id"] = remote_security_group.id
57
- end
58
- adapter.create_rule(security_group_id, rule["direction"], rule)
59
- end if diff[2]
60
- when "-"
61
- security_group = Kakine::Resource.security_group(options[:tenant], sg_name)
62
- adapter.delete_security_group(security_group.id)
58
+ case
59
+ when sg.add?
60
+ security_group_id = operation.create_security_group(sg)
61
+ operation.create_security_rule(sg, security_group_id)
62
+ when sg.delete?
63
+ operation.delete_security_group(sg)
64
+ when sg.update_attr?
65
+ operation.delete_security_group(sg)
66
+ security_group_id = operation.create_security_group(sg)
67
+ operation.create_security_rule(sg, security_group_id)
63
68
  else
64
69
  raise
65
70
  end
66
71
  end
67
72
  end
73
+ # update rule attributes delay create
74
+ delay_create.each do |sg|
75
+ operation.create_security_rule(sg)
76
+ end
68
77
  end
69
78
  end
70
79
  end
@@ -0,0 +1,44 @@
1
+ module Kakine
2
+ class CLI < Thor
3
+ class Operation
4
+ def set_adapter(adapter)
5
+ @adapter = adapter
6
+ end
7
+
8
+ def create_security_group(sg)
9
+ attributes = {name: sg.name, description: sg.description, tenant_id: sg.tenant_id}
10
+ security_group_id = @adapter.create_security_group(attributes)
11
+
12
+ #delete default rule
13
+ delete_sg = sg.clone
14
+ delete_sg.set_default_rules
15
+
16
+ delete_security_rule(delete_sg) unless @adapter.instance_of?(Kakine::Adapter::Mock)
17
+ security_group_id
18
+ end
19
+
20
+ def delete_security_group(sg)
21
+ security_group = Kakine::Resource.security_group(sg.tenant_name, sg.name)
22
+ @adapter.delete_security_group(security_group.id)
23
+ end
24
+
25
+ def create_security_rule(sg, security_group_id=nil)
26
+ if security_group_id.nil?
27
+ security_group = Kakine::Resource.security_group(sg.tenant_name, sg.name)
28
+ security_group_id = security_group.id
29
+ end
30
+ sg.rules.each do |rule|
31
+ @adapter.create_rule(security_group_id, rule["direction"], rule)
32
+ end if sg.has_rules?
33
+ end
34
+
35
+ def delete_security_rule(sg)
36
+ security_group = Kakine::Resource.security_group(sg.tenant_name, sg.name)
37
+ sg.rules.each do |rule|
38
+ security_group_rule = Kakine::Resource.security_group_rule(security_group, rule)
39
+ @adapter.delete_rule(security_group_rule.id)
40
+ end if sg.has_rules?
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,88 @@
1
+ module Kakine
2
+ class DiffParser
3
+ @diff = ""
4
+ class << self
5
+ def parse_parameters(tenant_name, diff)
6
+ @diff = diff
7
+
8
+ registered_sg = Kakine::Resource.security_groups_hash(tenant_name)
9
+ if ["+", "-"].include?(parse_transaction_type)
10
+ if unit_is_security_group?
11
+ rules = parse_security_group["rules"]
12
+ description = parse_security_group["description"]
13
+ elsif unit_is_security_rule?
14
+ rules = [parse_security_group_rule]
15
+ description = registered_sg[parse_security_group_name]["description"]
16
+ elsif unit_is_description?
17
+ raise "description is not exists"
18
+ end
19
+ else
20
+ regex_update_description = /^[\w-]+\.description$/
21
+ regex_update_rules = /^[\w-]+\.rules$/
22
+ regex_update_attr = /^[\w-]+.[\w]+\[(\d)\].([\w]+)$/
23
+
24
+ if parse_target_object_name.match(regex_update_description)
25
+ rules = registered_sg[parse_security_group_name]["rules"]
26
+ description = parse_after_description
27
+ elsif parse_target_object_name.match(regex_update_rules)
28
+ rules = parse_after_rules
29
+ description = registered_sg[parse_security_group_name]["description"]
30
+ elsif m = parse_target_object_name.match(regex_update_attr)
31
+ rules = [registered_sg[parse_security_group_name]["rules"][m[1].to_i]]
32
+ prev_rules = Marshal.load(Marshal.dump(rules)) # backup before value
33
+ rules[0][m[2]] = parse_after_attr
34
+ description = registered_sg[parse_security_group_name]["description"]
35
+ end
36
+ end
37
+ rules ||= []
38
+
39
+ {
40
+ target_object_name: parse_target_object_name,
41
+ name: parse_security_group_name,
42
+ transaction_type: parse_transaction_type,
43
+ tenant_id: Kakine::Resource.tenant(tenant_name).id,
44
+ tenant_name: tenant_name,
45
+ description: description,
46
+ rules: rules,
47
+ prev_rules: prev_rules
48
+ }
49
+ end
50
+
51
+ def parse_security_group_name
52
+ parse_target_object_name.split(/[\.\[]/, 2)[0]
53
+ end
54
+
55
+
56
+ def parse_transaction_type
57
+ @diff[0]
58
+ end
59
+
60
+ def parse_target_object_name
61
+ @diff[1]
62
+ end
63
+
64
+ def parse_security_group
65
+ @diff[2]
66
+ end
67
+ alias :parse_security_group_rule :parse_security_group
68
+
69
+ def parse_after_attr
70
+ @diff[3]
71
+ end
72
+ alias :parse_after_description :parse_after_attr
73
+ alias :parse_after_rules :parse_after_attr
74
+
75
+ def unit_is_security_group?
76
+ parse_security_group && parse_security_group["rules"]
77
+ end
78
+
79
+ def unit_is_security_rule?
80
+ !(parse_security_group_rule.nil? || unit_is_description?)
81
+ end
82
+
83
+ def unit_is_description?
84
+ parse_target_object_name.index('description')
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,13 @@
1
+ class Hash
2
+ def sg_rules_sort
3
+ self.each do |sg|
4
+ sg[1]['rules'].sort_by! do |rule|
5
+ rule.inject(0) do |ascii,(k,v)|
6
+ ascii += v.ord.to_i unless v.nil?
7
+ ascii
8
+ end
9
+ end unless sg[1].nil? || sg[1]['rules'].nil?
10
+ end
11
+ Hash[self]
12
+ end
13
+ end
@@ -1,13 +1,13 @@
1
+ require 'kakine/hash_sort'
1
2
  module Kakine
2
3
  class Resource
3
4
  class << self
4
5
  def yaml(filename)
5
- YAML.load_file(filename).to_hash
6
+ YAML.load_file(filename).to_hash.sg_rules_sort
6
7
  end
7
8
 
8
9
  def tenant(tenant_name)
9
- tenants = Fog::Identity[:openstack].tenants
10
- tenants.detect{|t| t.name == tenant_name}
10
+ @tenant ||= Fog::Identity[:openstack].tenants.detect{|t| t.name == tenant_name}
11
11
  end
12
12
 
13
13
  def security_group(tenant_name, security_group_name)
@@ -24,24 +24,31 @@ module Kakine
24
24
  sg.protocol == attributes["protocol"] &&
25
25
  sg.port_range_max == attributes["port_range_max"] &&
26
26
  sg.port_range_min == attributes["port_range_min"] &&
27
- sg.remote_ip_prefix == attributes["remote_ip"] &&
28
- sg.remote_group_id == attributes["remote_group_id"]
27
+ (
28
+ (
29
+ sg.remote_ip_prefix == attributes["remote_ip"] &&
30
+ sg.ethertype == attributes["ethertype"]
31
+ ) ||
32
+ (
33
+ sg.remote_group_id == attributes["remote_group_id"] &&
34
+ !attributes["remote_group_id"].nil?
35
+ )
36
+ )
29
37
  end
30
38
  end
31
39
 
32
40
  def security_groups_on_tenant(tenant_name)
33
- security_groups = Fog::Network[:openstack].security_groups
34
- security_groups.select{|sg| sg.tenant_id == tenant(tenant_name).id}
41
+ Fog::Network[:openstack].security_groups.select{|sg| sg.tenant_id == tenant(tenant_name).id}
35
42
  end
36
43
 
37
44
  def security_groups_hash(tenant_name)
38
- sg_hash = {}
45
+ sg_hash = Hash.new { |h,k| h[k] = {} }
39
46
 
40
47
  security_groups_on_tenant(tenant_name).each do |sg|
41
- sg_hash[sg.name] = format_security_group(sg)
48
+ sg_hash[sg.name]["rules"] = format_security_group(sg)
49
+ sg_hash[sg.name]["description"] = sg.description
42
50
  end
43
-
44
- sg_hash
51
+ sg_hash.sg_rules_sort
45
52
  end
46
53
 
47
54
  def format_security_group(security_group)
@@ -49,7 +56,6 @@ module Kakine
49
56
 
50
57
  security_group.security_group_rules.each do |rule|
51
58
  rule_hash = {}
52
-
53
59
  rule_hash["direction"] = rule.direction
54
60
  rule_hash["protocol"] = rule.protocol
55
61
 
@@ -65,11 +71,10 @@ module Kakine
65
71
  rule_hash["remote_group"] = response.data[:body]["security_group"]["name"]
66
72
  else
67
73
  rule_hash["remote_ip"] = rule.remote_ip_prefix
74
+ rule_hash["ethertype"] = rule.ethertype
68
75
  end
69
-
70
76
  rules << rule_hash
71
77
  end
72
-
73
78
  rules
74
79
  end
75
80
  end
@@ -0,0 +1,76 @@
1
+ module Kakine
2
+ class SecurityGroup
3
+ attr_reader :target_object_name, :name, :transaction_type, :tenant_id, :tenant_name, :description, :rules, :prev_rules
4
+
5
+ def initialize(tenant_name, diff)
6
+ unset_security_rules
7
+ Kakine::DiffParser.parse_parameters(tenant_name, diff).each do|k,v|
8
+ instance_variable_set(eval(":@#{k.to_s}"), v)
9
+ end
10
+ set_remote_security_group_id
11
+ end
12
+
13
+ def initialize_copy(obj)
14
+ @rules = Marshal.load(Marshal.dump(obj.rules))
15
+ @prev_rules = Marshal.load(Marshal.dump(obj.prev_rules))
16
+ unset_security_rules
17
+ end
18
+
19
+ def has_rules?
20
+ @rules.detect {|v| !v.nil? && v.size > 0}
21
+ end
22
+
23
+ def add?
24
+ @transaction_type == "+"
25
+ end
26
+
27
+ def delete?
28
+ @transaction_type == "-"
29
+ end
30
+
31
+ def update_attr?
32
+ @transaction_type == "~"
33
+ end
34
+
35
+ def update_rule?
36
+ !@target_object_name.split(/[\[]/, 2)[1].nil?
37
+ end
38
+
39
+ def get_prev_instance
40
+ prev_sg = self.clone
41
+ prev_sg.add_security_rules(@prev_rules)
42
+ prev_sg
43
+ end
44
+
45
+ def set_default_rules
46
+ unset_security_rules
47
+ ["IPv4", "IPv6"].each do |ip|
48
+ add_security_rules({"direction"=>"egress", "protocol"=>nil, "port"=>nil, "remote_ip"=>nil, "ethertype"=>ip})
49
+ end
50
+ end
51
+
52
+ def add_security_rules(rule)
53
+ case
54
+ when rule.instance_of?(Array)
55
+ @rules = rule
56
+ when rule.instance_of?(Hash)
57
+ @rules << rule
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def unset_security_rules
64
+ @rules = []
65
+ end
66
+
67
+ def set_remote_security_group_id
68
+ @rules.each do |rule|
69
+ unless rule['remote_group'].nil?
70
+ remote_security_group = Kakine::Resource.security_group(@tenant_name, rule.delete("remote_group"))
71
+ rule["remote_group_id"] = remote_security_group.id
72
+ end
73
+ end if has_rules?
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module Kakine
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kakine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SHIBATA Hiroshi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-04-27 00:00:00.000000000 Z
11
+ date: 2015-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog
@@ -131,7 +131,11 @@ files:
131
131
  - lib/kakine/adapter/mock.rb
132
132
  - lib/kakine/adapter/real.rb
133
133
  - lib/kakine/cli.rb
134
+ - lib/kakine/cli/operation.rb
135
+ - lib/kakine/diff_parser.rb
136
+ - lib/kakine/hash_sort.rb
134
137
  - lib/kakine/resource.rb
138
+ - lib/kakine/security_group.rb
135
139
  - lib/kakine/version.rb
136
140
  homepage: https://github.com/hsbt/kakine
137
141
  licenses:
@@ -153,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
157
  version: '0'
154
158
  requirements: []
155
159
  rubyforge_project:
156
- rubygems_version: 2.4.6
160
+ rubygems_version: 2.4.7
157
161
  signing_key:
158
162
  specification_version: 4
159
163
  summary: Security Group configuration tool for OpenStack.