kakine 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4768538b225d648ebf64a3eb52c7a2841cb14334
4
+ data.tar.gz: 5361d5d1eb968a8d238910ff5995fb4ee3b53592
5
+ SHA512:
6
+ metadata.gz: 5b8b3bc37780557a3c8fe2edd9209aa3f7f36e5de23bd0135f68aff7b541401609e4f77f70c04a3d0a6c803c4403c9d323be2e6d04bd2ed83ca5a620f4573cec
7
+ data.tar.gz: 5f8b2b5c7389bd4faea0752ff304dada6e433255d5dee7d926c7ec15df4d8281edab36b65597245e36f1157324caa7743c487354aa5ef5d13b4485de3b39bb88
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /*.yaml
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.6
5
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kakine.gemspec
4
+ gemspec
@@ -0,0 +1,83 @@
1
+ # Kakine
2
+
3
+ [![Build Status](https://secure.travis-ci.org/hsbt/kaname.png)](https://travis-ci.org/hsbt/kaname)
4
+
5
+ Kakine(垣根) is configuration management tool of Security Group on OpenStack.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'kakine'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install kakine
22
+
23
+ ## Usage
24
+
25
+ You can define Security Group configuration for OpenStack via YAML format. Like following syntax.
26
+
27
+ ```yaml
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
37
+ rails:
38
+ - direction: ingress
39
+ protocol: tcp
40
+ port: 3000
41
+ remote_ip: 0.0.0.0/0
42
+ ```
43
+
44
+ You need to put fog configuration to home directory.
45
+
46
+ ```sh
47
+ % cat ~/.fog
48
+ default:
49
+ openstack_auth_url: "http://your-openstack-endpoint/v2.0/tokens"
50
+ openstack_username: "admin"
51
+ openstack_tenant: "admin"
52
+ openstack_api_key: "admin-no-password"
53
+ ```
54
+
55
+ run following command.
56
+
57
+ ```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
+ ```
62
+
63
+ You can create or change Security Group on targeting tenant.
64
+
65
+ If you need to initialize your Security Gruop, you can get it via following command:
66
+
67
+ ```sh
68
+ $ kaname show tenant_name > tenant_name.yaml
69
+ ```
70
+
71
+ ## Development
72
+
73
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
74
+
75
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it ( https://github.com/hsbt/kakine/fork )
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/test_*.rb']
7
+ end
8
+
9
+ task(default: :test)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kakine"
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
@@ -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
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path("#{File.dirname __FILE__}/../lib")
4
+ require 'rubygems'
5
+ require 'kakine'
6
+
7
+ Kakine::CLI.start
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kakine/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kakine"
8
+ spec.version = Kakine::VERSION
9
+ spec.authors = ["SHIBATA Hiroshi"]
10
+ spec.email = ["hsbt@ruby-lang.org"]
11
+
12
+ spec.summary = %q{Security Group configuration tool for OpenStack.}
13
+ spec.description = %q{Security Group configuration tool for OpenStack. You can apply simple YAML definition into Security Group on OpenStack.}
14
+ spec.homepage = "https://github.com/hsbt/kakine"
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
+
22
+ spec.add_dependency 'fog'
23
+ spec.add_dependency 'thor'
24
+ spec.add_dependency 'hashdiff'
25
+
26
+ spec.add_development_dependency "bundler"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "minitest"
29
+ spec.add_development_dependency "mocha"
30
+ end
@@ -0,0 +1,7 @@
1
+ require "kakine/version"
2
+ require 'kakine/cli'
3
+ require 'kakine/adapter'
4
+ require 'kakine/resource'
5
+
6
+ module Kakine
7
+ end
@@ -0,0 +1,2 @@
1
+ require 'kakine/adapter/real'
2
+ require 'kakine/adapter/mock'
@@ -0,0 +1,34 @@
1
+ module Kakine
2
+ class Adapter
3
+ class Mock
4
+ def create_rule(security_group_id, direction, attributes)
5
+ attributes.delete("direction")
6
+ if attributes["port"]
7
+ attributes["port_range_max"] = attributes["port_range_min"] = attributes.delete("port")
8
+ end
9
+ if attributes["remote_ip"]
10
+ attributes["remote_ip_prefix"] = attributes.delete("remote_ip")
11
+ end
12
+
13
+ data = {}
14
+ attributes.each{|k,v| data[k.to_sym] = v}
15
+ puts "Create Rule: #{security_group_id} - #{direction}: #{attributes}"
16
+ end
17
+
18
+ def delete_rule(security_group_rule_id)
19
+ puts "Delete Rule: #{security_group_rule_id}"
20
+ end
21
+
22
+ def create_security_group(attributes)
23
+ data = {}
24
+ attributes.each{|k,v| data[k.to_sym] = v}
25
+ puts "Create Security Group: #{data}"
26
+ "[Mock] #{attributes[:name]} ID"
27
+ end
28
+
29
+ def delete_security_group(security_group_id)
30
+ puts "Delete Security Group: #{security_group_id}"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module Kakine
2
+ class Adapter
3
+ class Real
4
+ def create_rule(security_group_id, direction, attributes)
5
+ attributes.delete("direction")
6
+ if attributes["port"]
7
+ attributes["port_range_max"] = attributes["port_range_min"] = attributes.delete("port")
8
+ end
9
+ if attributes["remote_ip"]
10
+ attributes["remote_ip_prefix"] = attributes.delete("remote_ip")
11
+ end
12
+
13
+ data = {}
14
+ attributes.each{|k,v| data[k.to_sym] = v}
15
+ Fog::Network[:openstack].create_security_group_rule(security_group_id, direction, data)
16
+ end
17
+
18
+ def delete_rule(security_group_rule_id)
19
+ Fog::Network[:openstack].delete_security_group_rule(security_group_rule_id)
20
+ end
21
+
22
+ def create_security_group(attributes)
23
+ data = {}
24
+ attributes.each{|k,v| data[k.to_sym] = v}
25
+ response = Fog::Network[:openstack].create_security_group(data)
26
+ response.data[:body]["security_group"]["id"]
27
+ end
28
+
29
+ def delete_security_group(security_group_id)
30
+ Fog::Network[:openstack].delete_security_group(security_group_id)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,70 @@
1
+ require 'thor'
2
+ require 'fog'
3
+ require 'yaml'
4
+ require 'hashdiff'
5
+
6
+ module Kakine
7
+ class CLI < Thor
8
+ option :tenant, type: :string, aliases: '-t'
9
+ desc 'show', 'show Security Groups specified tenant'
10
+ def show
11
+ puts Kakine::Resource.security_groups_hash(options[:tenant]).to_yaml
12
+ end
13
+
14
+ option :tenant, type: :string, aliases: "-t"
15
+ option :dryrun, type: :boolean, aliases: "-d"
16
+ option :filename, type: :string, aliases: "-f"
17
+ desc 'apply', "apply local configuration into OpenStack"
18
+ def apply
19
+ adapter = if options[:dryrun]
20
+ Kakine::Adapter::Mock.new
21
+ else
22
+ Kakine::Adapter::Real.new
23
+ end
24
+
25
+ filename = options[:filename] ? options[:filename] : "#{options[:tenant]}.yaml"
26
+ diffs = HashDiff.diff(Kakine::Resource.security_groups_hash(options[:tenant]), Kakine::Resource.yaml(filename))
27
+
28
+ diffs.each do |diff|
29
+ sg_name, rule_modification = *diff[1].scan(/^([\w-]+)(\[\d\])?/)[0]
30
+
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)
44
+ else
45
+ raise
46
+ end
47
+ 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)
63
+ else
64
+ raise
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,77 @@
1
+ module Kakine
2
+ class Resource
3
+ class << self
4
+ def yaml(filename)
5
+ YAML.load_file(filename).to_hash
6
+ end
7
+
8
+ def tenant(tenant_name)
9
+ tenants = Fog::Identity[:openstack].tenants
10
+ tenants.detect{|t| t.name == tenant_name}
11
+ end
12
+
13
+ def security_group(tenant_name, security_group_name)
14
+ security_groups_on_tenant(tenant_name).detect{|sg| sg.name == security_group_name}
15
+ end
16
+
17
+ def security_group_rule(security_group, attributes)
18
+ security_group.security_group_rules.detect do |sg|
19
+ if attributes["port"]
20
+ attributes["port_range_max"] = attributes["port_range_min"] = attributes["port"]
21
+ end
22
+
23
+ sg.direction == attributes["direction"] &&
24
+ sg.protocol == attributes["protocol"] &&
25
+ sg.port_range_max == attributes["port_range_max"] &&
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"]
29
+ end
30
+ end
31
+
32
+ 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}
35
+ end
36
+
37
+ def security_groups_hash(tenant_name)
38
+ sg_hash = {}
39
+
40
+ security_groups_on_tenant(tenant_name).each do |sg|
41
+ sg_hash[sg.name] = format_security_group(sg)
42
+ end
43
+
44
+ sg_hash
45
+ end
46
+
47
+ def format_security_group(security_group)
48
+ rules = []
49
+
50
+ security_group.security_group_rules.each do |rule|
51
+ rule_hash = {}
52
+
53
+ rule_hash["direction"] = rule.direction
54
+ rule_hash["protocol"] = rule.protocol
55
+
56
+ if rule.port_range_max == rule.port_range_min
57
+ rule_hash["port"] = rule.port_range_max
58
+ else
59
+ rule_hash["port_range_max"] = rule.port_range_max
60
+ rule_hash["port_range_min"] = rule.port_range_min
61
+ end
62
+
63
+ if rule.remote_group_id
64
+ response = Fog::Network[:openstack].get_security_group(rule.remote_group_id)
65
+ rule_hash["remote_group"] = response.data[:body]["security_group"]["name"]
66
+ else
67
+ rule_hash["remote_ip"] = rule.remote_ip_prefix
68
+ end
69
+
70
+ rules << rule_hash
71
+ end
72
+
73
+ rules
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ module Kakine
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kakine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - SHIBATA Hiroshi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-04-27 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: hashdiff
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: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
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: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mocha
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Security Group configuration tool for OpenStack. You can apply simple
112
+ YAML definition into Security Group on OpenStack.
113
+ email:
114
+ - hsbt@ruby-lang.org
115
+ executables:
116
+ - kakine
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/setup
127
+ - exe/kakine
128
+ - kakine.gemspec
129
+ - lib/kakine.rb
130
+ - lib/kakine/adapter.rb
131
+ - lib/kakine/adapter/mock.rb
132
+ - lib/kakine/adapter/real.rb
133
+ - lib/kakine/cli.rb
134
+ - lib/kakine/resource.rb
135
+ - lib/kakine/version.rb
136
+ homepage: https://github.com/hsbt/kakine
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.4.6
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: Security Group configuration tool for OpenStack.
160
+ test_files: []
161
+ has_rdoc: