demeter-cli 0.0.4

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: f8cd0a1932dcbadb7009e697cfd074370cd00647
4
+ data.tar.gz: e446ff1b2a1b9f75f60ae032ef5e419c5a5f9188
5
+ SHA512:
6
+ metadata.gz: 928c88dae96a2b06aa246b030b1863b3c36bf3109d670f518aa391e7ebacdafd27054aba1bc5a2313876427ebfa9aef0a51a1ae4efdb4426234e1e0ede47c4f6
7
+ data.tar.gz: 4cb19d326eb8cb3f7d0999612d5c722a82627bfe6a3ee4c4c196ae8fa597ec5373a4618df645d527fb7a07320377c7a0ad3608de5dd62507aed1a30e5be503e5
@@ -0,0 +1,2 @@
1
+ p-��Ӡ�C��SkU݂����r(���55�y�ه�̚\�wg�V���@�[�Gf�?�ބl�6o���Z��1B ���*S�3� �'�-cm ��:U�Z�!���Ukz`�z8�r]�����|Wv�"]Ay6����2Cg��w��I�Wd914ہ��Y�«6B����Mu�me|*,�l9�N����ƅ����X�\�-
2
+ F���rx�n�ꆵ��� T��'$o�#��bRf[\��F��2�Ls��d
@@ -0,0 +1,3 @@
1
+ a
2
+ �ˊj�f���7�L���jv&����ћ���VK�� �*�����>����CS.��<��y
3
+ 4� ��n����w�pA�ֿko5�C ZW
@@ -0,0 +1,6 @@
1
+ .env*
2
+ *.sw*
3
+ pkg/
4
+ .DS_Store
5
+ coverage/
6
+ *.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
File without changes
@@ -0,0 +1,50 @@
1
+ Demeter is an open source project and we would love you to help us make it better.
2
+
3
+ ## Reporting Issues
4
+
5
+ A well formatted issue is appreciated, and goes a long way in helping us help you.
6
+
7
+ * Make sure you have a [GitHub account](https://github.com/signup/free)
8
+ * Submit a [Github issue](./issues) by:
9
+ * Clearly describing the issue
10
+ * Provide a descriptive summary
11
+ * Explain the expected behavior
12
+ * Explain the actual behavior
13
+ * Provide steps to reproduce the actual behavior
14
+ * Provide your application's complete `Gemfile.lock` as text (in a [Gist](https://gist.github.com) for bonus points)
15
+ * Any relevant stack traces
16
+
17
+ If you provide code, make sure it is formatted with the triple backticks (\`).
18
+
19
+ ## Pull requests
20
+
21
+ We accept pull requests to Demeter for:
22
+
23
+ * Adding documentation
24
+ * Fixing bugs
25
+ * Adding new features
26
+
27
+ Not all features proposed will be added but we are open to having a conversation
28
+ about a feature you are championing.
29
+
30
+ Here's a quick guide:
31
+
32
+ 1. Fork the repo.
33
+
34
+ 2. Run the tests. This is to make sure your starting point works. Tests can be
35
+ run via `rake spec`
36
+
37
+ 3. Create a new branch and make your changes. This includes tests for features!
38
+
39
+ 4. Push to your fork and submit a pull request. For more information, see
40
+ [Github's pull request help section](https://help.github.com/articles/using-pull-requests/).
41
+
42
+ At this point you're waiting on us. Expect a conversation regarding your pull
43
+ request; Questions, clarifications, and so on.
44
+
45
+ Some things that will increase the chance that your pull request is accepted:
46
+
47
+ * Use Demeter idioms
48
+ * Include tests that fail without your code, and pass with it
49
+ * Update the documentation, guides, etc.
50
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ ruby '2.2.2'
4
+ gem 'simplecov', :require => false, :group => :test
@@ -0,0 +1,67 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ demeter (0.0.1)
5
+ aws-sdk (~> 2.1)
6
+ bundler (~> 1.6)
7
+ colorize (~> 0.7)
8
+ hashdiff (~> 0.2)
9
+ terminal-table (~> 1.5)
10
+ thor (~> 0.19)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ aws-sdk (2.1.30)
16
+ aws-sdk-resources (= 2.1.30)
17
+ aws-sdk-core (2.1.30)
18
+ jmespath (~> 1.0)
19
+ aws-sdk-resources (2.1.30)
20
+ aws-sdk-core (= 2.1.30)
21
+ coderay (1.1.0)
22
+ colorize (0.7.7)
23
+ diff-lcs (1.2.5)
24
+ docile (1.1.5)
25
+ hashdiff (0.2.2)
26
+ jmespath (1.1.3)
27
+ json (1.8.3)
28
+ method_source (0.8.2)
29
+ pry (0.10.3)
30
+ coderay (~> 1.1.0)
31
+ method_source (~> 0.8.1)
32
+ slop (~> 3.4)
33
+ rake (10.4.2)
34
+ rspec (3.3.0)
35
+ rspec-core (~> 3.3.0)
36
+ rspec-expectations (~> 3.3.0)
37
+ rspec-mocks (~> 3.3.0)
38
+ rspec-core (3.3.2)
39
+ rspec-support (~> 3.3.0)
40
+ rspec-expectations (3.3.1)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.3.0)
43
+ rspec-mocks (3.3.2)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.3.0)
46
+ rspec-support (3.3.0)
47
+ simplecov (0.10.0)
48
+ docile (~> 1.1.0)
49
+ json (~> 1.8)
50
+ simplecov-html (~> 0.10.0)
51
+ simplecov-html (0.10.0)
52
+ slop (3.6.0)
53
+ terminal-table (1.5.2)
54
+ thor (0.19.1)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ demeter!
61
+ pry
62
+ rake (~> 10)
63
+ rspec (~> 3.3)
64
+ simplecov
65
+
66
+ BUNDLED WITH
67
+ 1.10.6
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Coinbase Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,62 @@
1
+ # Demeter
2
+
3
+ Demeter is a command line tool for managing security groups across multiple AWS environments. Demeter was written with the following goals:
4
+ * __Stateless.__ EC2 tags are used to store all metadata about security groups. This makes it easy for collaborators to make changes to security groups.
5
+ * __Variables.__ Provides a flexible way to define global and per-environment variables to be used in all templates.
6
+ * __Multiple AWS Accounts.__ Maintain a naming scheme for your security groups that can be applied to any region or AWS account.
7
+ * __Infrastructure as code.__ My maintaining your security groups using a demeter repository makes them easy to edit and collaborate on.
8
+
9
+ ## Installation
10
+
11
+ ```shell
12
+ % gem install demeter-cli
13
+ ```
14
+
15
+
16
+ ## Usage
17
+
18
+ [**Detailed instructions - Demeter Example Project**](https://github.com/coinbase/demeter-example)
19
+
20
+ ## Available Commands
21
+
22
+ `-environment` or short `-e` is a required parameter. It loads the environment variables and sources `.env.<environment>` file
23
+
24
+ Show general help or specific command help
25
+ ```
26
+ $ demeter help <command>
27
+ ```
28
+
29
+ Get list of all managed and unmanaged security groups
30
+ ```
31
+ $ demeter status -e staging
32
+ ```
33
+
34
+ Run a plan against environment and return a diff between local state
35
+ ```
36
+ $ demeter plan -e staging
37
+ ```
38
+
39
+ Apply diff changes
40
+ ```
41
+ $ demeter apply -e staging
42
+ ```
43
+
44
+ When migrating existing security groups you can generate config by specifying existing security group ids
45
+ ```
46
+ $ demeter generate -e staging -ids sg-111111 sg-22222
47
+ ```
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it ( https://github.com/coinbase/demeter/fork )
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create a new Pull Request
56
+
57
+ You can use `rake install` to install and test your local development gem
58
+
59
+ ## Copyright
60
+
61
+ Copyright © 2015 Coinbase Inc. – Released under MIT License
62
+
@@ -0,0 +1,14 @@
1
+ require 'rake'
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new
6
+
7
+ namespace :test do
8
+ task :coverage do
9
+ ENV['COVERAGE'] = 'true'
10
+ Rake::Task['test'].invoke
11
+ end
12
+ end
13
+
14
+ task :default => :spec
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ require 'demeter'
3
+ require 'demeter/cli'
4
+ require 'dotenv'
5
+
6
+ begin
7
+ Demeter::Cli.start
8
+ rescue => e
9
+ puts "Error during processing: #{$!}"
10
+ puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if ARGV.include?('--debug')
11
+ end
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdzdXBw
3
+ b3J0MRgwFgYKCZImiZPyLGQBGRYIY29pbmJhc2UxEzARBgoJkiaJk/IsZAEZFgNj
4
+ b20wHhcNMTUxMTIwMjAyNjMxWhcNMTYxMTE5MjAyNjMxWjBBMRAwDgYDVQQDDAdz
5
+ dXBwb3J0MRgwFgYKCZImiZPyLGQBGRYIY29pbmJhc2UxEzARBgoJkiaJk/IsZAEZ
6
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDG5tBNXR1U7v0+
7
+ hc6LyPa9I2yaXpV0SZzMTGUPZV6SeOSCQR2rX7gCdMOwOHw40zgp9UKo/1TgrefU
8
+ sr1gW2G924QIEFKT+ntl01Qp5oexk7o3Ur/h+u2VQmPcqb9oQ/1HTCEMKYJiZkOq
9
+ UZG4HVtWfo1NB6CmfbKV4TZQtxSg0CmPEgvY5pSMZISQU+jf0EEtnJcqlxjSCK24
10
+ bOj57GnkBeYtdoU+7rGWaUcNlrdZRL7osFePWVCJLI8D/NHEQQO61E9kjcw68RxB
11
+ 3TX+IoZxlQgsJ3vQUJRwSynloRSeEvHRkRD5M9p8XaD2Xrmb/jNTkSAARP+z+W4Y
12
+ P6MMErQ3AgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
13
+ BBRZsjqnPq839UVVUohuyqSaxo7G0DAfBgNVHREEGDAWgRRzdXBwb3J0QGNvaW5i
14
+ YXNlLmNvbTAfBgNVHRIEGDAWgRRzdXBwb3J0QGNvaW5iYXNlLmNvbTANBgkqhkiG
15
+ 9w0BAQUFAAOCAQEAU39cPSHZwN+Y25YFyQx5EZMdyEOERXCf8/Pfvit7x5Yt8MXw
16
+ bygBPLsCkcEe+FbQOaG9xba1SAknR2iMreup2XjUFl9hh5PM8VLX1zNukgmYuui+
17
+ ENY3lM0N1v482XJ0fdfbg43g9Ss8/JnXMplVJgWLTp+yTCUIMoW1mnarvxHZomzb
18
+ UL9hDd7K8HzMSwi5byL9o4LfQqTwjxBgWY76uROt0pNTPtcuXrnkKqSHwgwZ5RmH
19
+ vMBSV8F4fVD4X38X65JM6sekvTV2g7EfEWXUYRpo+GbTO447fdHbeSeA9LeYTY40
20
+ BrzC5KFFAVcr7Bl/R6Jdzbj7ZlhwFUize0CjOw==
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'demeter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'demeter-cli'
8
+ spec.version = Demeter::VERSION
9
+ spec.authors = ['Saso Matejina', 'Jeremy Deininger']
10
+ spec.email = []
11
+ spec.summary = %q{A complete manager for AWS security groups}
12
+ spec.description = %q{A complete manager for AWS security groups}
13
+ spec.homepage = 'https://github.com/coinbase/demeter'
14
+ spec.license = 'MIT'
15
+ spec.cert_chain = ['certs/coinbase.pem']
16
+ spec.signing_key = File.expand_path("~/.ssh/coinbase-gem-private_key.pem") if $0 =~ /gem\z/
17
+
18
+ spec.files = `git ls-files`.split("\n")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(spec)/})
21
+ spec.require_paths = ['lib']
22
+ spec.required_ruby_version = '>= 2.0.0'
23
+
24
+ spec.add_dependency 'thor', '~> 0.19'
25
+ spec.add_dependency 'aws-sdk', '~> 2.1'
26
+ spec.add_dependency 'hashdiff', '~> 0.2'
27
+ spec.add_dependency 'bundler', '~> 1.6'
28
+ spec.add_dependency 'colorize', '~> 0.7'
29
+ spec.add_dependency 'terminal-table', '~> 1.5'
30
+ spec.add_dependency 'dotenv', '~> 2.0'
31
+
32
+ spec.add_development_dependency 'rake', '~> 10'
33
+ spec.add_development_dependency 'rspec', '~> 3.3'
34
+ spec.add_development_dependency 'pry'
35
+ end
@@ -0,0 +1,48 @@
1
+ require 'demeter/version'
2
+
3
+ module Demeter
4
+ DEFAULT_ENV = 'development'.freeze
5
+
6
+ def self.root(root=nil)
7
+ if root
8
+ @root ||= root
9
+ else
10
+ @root ||= Pathname.new(Dir.pwd)
11
+ end
12
+ end
13
+
14
+ def self.env
15
+ @environment ||= ENV['DEMETER_ENV'] || ENV['ENV'] || DEFAULT_ENV
16
+ end
17
+
18
+ def self.vars
19
+ @vars ||= begin
20
+ global_vars = {}
21
+ env_vars = {}
22
+ global_path = File.join(Demeter::root, "/variables/global.yml")
23
+ environment_path = File.join(Demeter::root, "/variables/#{self.env}.yml")
24
+
25
+ if File.exists?(global_path)
26
+ global_vars = YAML::load_file(global_path)
27
+ global_vars = Hash[global_vars.map{|k,v| ["global.#{k}",v]}]
28
+ else
29
+ fail "Global file /variables/global.yml not found! Add it before rerunning..."
30
+ end
31
+
32
+ if File.exists?(environment_path)
33
+ env_vars = YAML::load_file(environment_path)
34
+ env_vars = Hash[env_vars.map{|k,v| ["env.#{k}",v]}]
35
+ else
36
+ fail "Environment file /variables/#{Demeter::env}.yml not found! Add it before rerunning..."
37
+ end
38
+
39
+ global_vars.merge!(env_vars)
40
+ end
41
+ end
42
+
43
+ def self.set_var(key, value)
44
+ vars = self.vars
45
+ vars[key] = value
46
+ @vars = vars
47
+ end
48
+ end
@@ -0,0 +1,113 @@
1
+ require 'aws-sdk'
2
+ require 'yaml'
3
+ require 'demeter/aws/security_group.rb'
4
+ require 'colorize'
5
+
6
+ module Demeter
7
+ module Aws
8
+ class ManageSecurityGroups
9
+ def initialize(ec2:, project_path: File.join(Demeter::root, "/configs/**/*.yml"), options:{})
10
+ @ec2 = ec2
11
+ @sgs = {}
12
+ @project_path = project_path
13
+ @options = options
14
+ end
15
+
16
+ # Returns array of diffs
17
+ def diff_all
18
+ describe
19
+ all_diffs = {}
20
+ @sgs.each do |key, sg|
21
+ diff = sg.diff
22
+ if diff.any?
23
+ all_diffs[key] = diff
24
+ end
25
+ end
26
+ all_diffs
27
+ end
28
+
29
+ def create_all
30
+ describe
31
+ @sgs.each do |key, sg|
32
+ sg.create
33
+ end
34
+ end
35
+
36
+ def modify_all
37
+ describe
38
+ @sgs.each do |key, sg|
39
+ sg.modify
40
+ end
41
+ end
42
+
43
+ def apply
44
+ create_all
45
+ modify_all
46
+ end
47
+
48
+ def status
49
+ status = {managed: [], unmanaged: []}
50
+ local_sgs = []
51
+
52
+ Dir.glob(@project_path).each do |path|
53
+ project_config = YAML::load_file(path)
54
+
55
+ next if !project_config
56
+ next if project_config['environments'] && @options['environment'] && !project_config['environments'].include?(@options['environment'])
57
+
58
+ if project_config && project_config['security_groups']
59
+ project_config['security_groups'].each do |local_sg|
60
+ local_sgs << local_sg['name']
61
+ end
62
+ end
63
+ end
64
+
65
+ res = @ec2.describe_security_groups
66
+ res[:security_groups].each do |object|
67
+ name_tag = object['tags'].detect{|tag| tag['key'].downcase == 'name'}
68
+ if name_tag && local_sgs.include?(name_tag['value'])
69
+ status[:managed] << {
70
+ name: name_tag['value'],
71
+ group_id: object.group_id,
72
+ group_name: object.group_name
73
+ }
74
+ else
75
+ status[:unmanaged] << {
76
+ name: (name_tag ? name_tag['value'] : ''),
77
+ group_id: object.group_id,
78
+ group_name: object.group_name
79
+ }
80
+ end
81
+ end
82
+ status[:managed].sort_by!{|x| x[:name]}
83
+ status[:unmanaged].sort_by!{|x| x[:name]}
84
+ status
85
+ end
86
+
87
+ def describe()
88
+ Dir.glob(@project_path).each do |path|
89
+ project_config = YAML::load_file(path)
90
+
91
+ next if !project_config
92
+ next if project_config['environments'] && @options['environment'] && !project_config['environments'].include?(@options['environment'])
93
+
94
+ if project_config && project_config['security_groups']
95
+ project_config['security_groups'].each do |local_sg|
96
+ sg = Demeter::Aws::SecurityGroup.new(@ec2)
97
+ sg.load_local(local_sg)
98
+ @sgs[sg.hash] = sg
99
+ end
100
+ end
101
+ end
102
+
103
+ res = @ec2.describe_security_groups
104
+ res[:security_groups].each do |object|
105
+ name_tag = object['tags'].detect{|tag| tag['key'].downcase == 'name'}
106
+ if name_tag && @sgs.include?(name_tag['value'])
107
+ @sgs[name_tag['value']].load_aws(object)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end