debut 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README.md +100 -0
  2. data/bin/debut +79 -0
  3. data/lib/debut/aws.rb +167 -0
  4. data/lib/debut/version.rb +20 -0
  5. data/lib/debut.rb +105 -0
  6. metadata +120 -0
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ ![livetribe](http://en.gravatar.com/userimage/37511139/d08dfb0c999f540b24b0e042d27e5b17.png)
2
+
3
+ LiveTribe Debut
4
+ ===============
5
+ [![Build Status](https://secure.travis-ci.org/livetribe/livetribe-debut.png?branch=master)](http://travis-ci.org/livetribe/livetribe-debut)
6
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/debut.png)](http://badge.fury.io/rb/debut)
7
+ [![Dependency Status](https://gemnasium.com/livetribe/livetribe-debut.png)](https://gemnasium.com/livetribe/livetribe-debut)
8
+ [![Code Climate](https://codeclimate.com/github/livetribe/livetribe-debut.png)](https://codeclimate.com/github/livetribe/livetribe-debut)
9
+ [![Coverage Status](https://coveralls.io/repos/livetribe/livetribe-debut/badge.png)](https://coveralls.io/r/livetribe/livetribe-debut)
10
+
11
+ Register your cloud instance w/ DNS and other lookup services.
12
+
13
+ ## About
14
+
15
+ LiveTribe's `debut` command can be used to register your cloud instance with a
16
+ DNS service, e.g. Amazon Route 53. It can also be used to unregister your
17
+ cloud instance as well.
18
+
19
+ The `debut` command allows for the addition of providers which allow the
20
+ `debut` command to interface with different DNS providers. At the moment
21
+ there is only one Amazon Route 53 provider. Come join the fun and add one!
22
+
23
+ ## Getting Started
24
+
25
+ sudo gem install debut
26
+
27
+ Now, after
28
+ [setting up your Fog credentials]http://fog.io/about/getting_started.html#credentials "Setting up your Fog credentials"),
29
+ you are ready to introduce your cloud instance:
30
+
31
+ $ debut -h ec2-164-62-8-61.us-west-1.compute.amazonaws.com -s mock.livetribe.org. -n travis hello
32
+ Registered hostname ec2-164-62-8-61.us-west-1.compute.amazonaws.com at travis.mock.livetribe.org.
33
+ $ debut -h ec2-164-62-8-61.us-west-1.compute.amazonaws.com -s mock.livetribe.org. -n travis goodbye
34
+ Unregistered travis.mock.livetribe.org.
35
+
36
+ If the hostname, sub-domain, and name are not specified, the `aws` provider
37
+ will attempt obtain the information from the
38
+ [user data of the meta-data service](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html).
39
+ Here, the `aws` provider will be looking for a valid JSON object:
40
+
41
+ {
42
+ "hostname": "ec2-184-72-8-21.us-west-1.compute.amazonaws.com",
43
+ "subdomain": "mock.livetribe.org.",
44
+ "name": "travis"
45
+ }
46
+
47
+ If any of the above parameters are not specified in the user data they must be
48
+ provided on the command line.
49
+
50
+ ### AWS Policies
51
+
52
+ The AWS security policy for the user must allow for the reading of the list of
53
+ zones and for the modification of the zone onto which `CNAME` records will be
54
+ added. The following represents the minimum policy which seems to work:
55
+
56
+ {
57
+ "Version": "2012-10-17",
58
+ "Statement": [
59
+ {
60
+ "Effect": "Allow",
61
+ "Action": [
62
+ "route53:Get*",
63
+ "route53:List*"
64
+ ],
65
+ "Resource": [
66
+ "*"
67
+ ]
68
+ },
69
+ {
70
+ "Action": [
71
+ "route53:ChangeResourceRecordSets"
72
+ ],
73
+ "Resource": [
74
+ "arn:aws:route53:::hostedzone/YOURHOSTEDZONEID"
75
+ ],
76
+ "Effect": "Allow"
77
+ }
78
+ ]
79
+ }
80
+
81
+ Where `YOURHOSTEDZONEID` needs to be replaced with the zone id of your Amazon
82
+ Route 53 zone. The first policy statement allows for the scanning of zones and
83
+ the second policy allows for the modification of a specific zone.
84
+
85
+ ## Contributing
86
+
87
+ * Find something you would like to work on.
88
+ * Look for anything you can help with in the [issue tracker](https://github.com/livetribe/livetribe-debut/issues).
89
+ * Look at the [code quality metrics](https://codeclimate.com/github/livetribe/livetribe-debut) for anything you can help clean up.
90
+ * Or anything else!
91
+ * Fork the project and do your work in a topic branch.
92
+ * Make sure your changes will work on both Ruby 1.9 and Ruby 2.0
93
+ * Add minitests tests to prove your code works and run all the tests using `bundle exec rake`.
94
+ * Rebase your branch against `livetribe/livetribe-debut` to make sure everything is up to date.
95
+ * Commit your changes and send a pull request.
96
+
97
+ ## Additional Resources
98
+
99
+ * [livetribe.org](http://www.livetribe.org)
100
+ * [Provider Documentation](http://www.livetribe.org/about/Debut-Provider)
data/bin/debut ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright 2013 the original author or authors
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ #
18
+
19
+ require 'gli'
20
+
21
+ include GLI::App
22
+
23
+ program_desc 'Register your cloud instance w/ DNS and other lookup services'
24
+
25
+ version Debut::VERSION
26
+
27
+ desc 'Use local hostname'
28
+ switch [:l,:local], :default_value => LiveTribe::Debut::Debutante::USE_LOCAL_HOSTNAME
29
+
30
+ desc 'The Fog provider'
31
+ default_value 'aws'
32
+ arg_name 'provider'
33
+ flag [:p,:provider]
34
+
35
+ desc 'The hostname of the cloud instance'
36
+ default_value LiveTribe::Debut::Debutante::USE_ENVIRONMENT
37
+ arg_name 'hostname'
38
+ flag [:h,:hostname]
39
+
40
+ desc 'The name of the cloud instance'
41
+ default_value LiveTribe::Debut::Debutante::USE_ENVIRONMENT
42
+ arg_name 'name'
43
+ flag [:n,:name]
44
+
45
+ desc 'The subdomain of the cloud instance'
46
+ default_value LiveTribe::Debut::Debutante::USE_ENVIRONMENT
47
+ arg_name 'subdomain'
48
+ flag [:s,:subdomain]
49
+
50
+ desc 'Announce the arrival of your cloud instance to the world'
51
+ command :hello do |c|
52
+ c.action do |global_options, options, args|
53
+ provider = global_options[:provider]
54
+
55
+ debutant = LiveTribe::Debut::Debutante::new({:provider => provider})
56
+ debutant.hostname = global_options[:hostname]
57
+ debutant.name = global_options[:name]
58
+ debutant.subdomain = global_options[:subdomain]
59
+ debutant.use_local_hostname = global_options[:local]
60
+
61
+ debutant.hello
62
+ end
63
+ end
64
+
65
+ desc 'Announce the departure of your cloud instance to the world'
66
+ command :goodbye do |c|
67
+ c.action do |global_options, options, args|
68
+ provider = global_options[:provider]
69
+
70
+ debutant = LiveTribe::Debut::Debutante::new({:provider => provider})
71
+ debutant.hostname = global_options[:hostname]
72
+ debutant.name = global_options[:name]
73
+ debutant.subdomain = global_options[:subdomain]
74
+
75
+ debutant.goodbye
76
+ end
77
+ end
78
+
79
+ exit run(ARGV)
data/lib/debut/aws.rb ADDED
@@ -0,0 +1,167 @@
1
+ #
2
+ # Copyright 2013 the original author or authors
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing,
11
+ # software distributed under the License is distributed on an
12
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ # KIND, either express or implied. See the License for the
14
+ # specific language governing permissions and limitations
15
+ # under the License.
16
+ #
17
+
18
+ module LiveTribe
19
+ module Debut
20
+ INSTANCE_METADATA_HOST = 'http://169.254.169.254'
21
+ INSTANCE_METADATA_PATH = '/latest/user-data'
22
+ INSTANCE_LOCAL_HOSTNAME_PATH = '/latest/meta-data/local-hostname'
23
+ INSTANCE_PUBLIC_HOSTNAME_PATH = '/latest/meta-data/public-hostname'
24
+
25
+ class AWS < LiveTribe::Debut::Provider
26
+ require 'json'
27
+ require 'fog'
28
+
29
+ def initialize(attributes)
30
+ @dns = Fog::DNS.new(attributes)
31
+
32
+ @hostname = LiveTribe::Debut::Debutante::USE_ENVIRONMENT
33
+ @name = LiveTribe::Debut::Debutante::USE_ENVIRONMENT
34
+ @subdomain = LiveTribe::Debut::Debutante::USE_ENVIRONMENT
35
+ @use_local_hostname = LiveTribe::Debut::Debutante::USE_LOCAL_HOSTNAME
36
+ end
37
+
38
+ def hostname
39
+ @hostname
40
+ end
41
+
42
+ def hostname=(hostname)
43
+ @hostname = hostname
44
+ end
45
+
46
+ def name
47
+ @name
48
+ end
49
+
50
+ def name=(name)
51
+ @name = name
52
+ end
53
+
54
+ def subdomain
55
+ @subdomain
56
+ end
57
+
58
+ def subdomain=(subdomain)
59
+ @subdomain = subdomain
60
+ end
61
+
62
+ def use_local_hostname
63
+ @use_local_hostname
64
+ end
65
+
66
+ def use_local_hostname=(use_local_hostname)
67
+ @use_local_hostname = use_local_hostname
68
+ end
69
+
70
+ def to_s
71
+ 'aws'
72
+ end
73
+
74
+ def hello
75
+ name, subdomain = collect_name_and_subdomain
76
+ hostname = collect_hostname
77
+ fqdn = "#{name}.#{subdomain}"
78
+ for zone in @dns.zones
79
+ if zone.domain == subdomain
80
+ record = zone.records.find { |r| r.name == fqdn && r.type == 'CNAME' }
81
+ if record
82
+ puts "Destroying old record for #{fqdn}"
83
+
84
+ record.destroy
85
+ end
86
+
87
+ zone.records.create(
88
+ :value => hostname,
89
+ :name => fqdn,
90
+ :type => 'CNAME'
91
+ )
92
+
93
+ puts "Registered hostname #{hostname} at #{fqdn}"
94
+
95
+ return
96
+ end
97
+ end
98
+ raise ArgumentError.new("Unable to find route53 zone: #{subdomain}")
99
+ end
100
+
101
+ def goodbye
102
+ name, subdomain = collect_name_and_subdomain
103
+ fqdn = "#{name}.#{subdomain}"
104
+ @dns.zones.each { |zone|
105
+ if zone.domain == subdomain
106
+ record = zone.records.find { |r| r.name == fqdn && r.type == 'CNAME' }
107
+ if record
108
+ record.destroy
109
+ end
110
+
111
+ puts "Unregistered #{fqdn}"
112
+
113
+ return
114
+ end
115
+ }
116
+ raise ArgumentError.new("Unable to find route53 zone: #{subdomain}")
117
+ end
118
+
119
+ protected
120
+
121
+ def collect_name_and_subdomain
122
+ name = @name
123
+ subdomain = @subdomain
124
+
125
+ if name == LiveTribe::Debut::Debutante::USE_ENVIRONMENT || subdomain == LiveTribe::Debut::Debutante::USE_ENVIRONMENT
126
+ connection = Excon.new(INSTANCE_METADATA_HOST)
127
+ metadata = Fog::JSON.decode(connection.get(:path => INSTANCE_METADATA_PATH, :expects => 200).body)
128
+ metadata.default = LiveTribe::Debut::Debutante::USE_ENVIRONMENT
129
+
130
+ if name == LiveTribe::Debut::Debutante::USE_ENVIRONMENT
131
+ name = metadata['name']
132
+ end
133
+
134
+ if subdomain == LiveTribe::Debut::Debutante::USE_ENVIRONMENT
135
+ subdomain = metadata['subdomain']
136
+ end
137
+ end
138
+
139
+ if name == LiveTribe::Debut::Debutante::USE_ENVIRONMENT || subdomain == LiveTribe::Debut::Debutante::USE_ENVIRONMENT
140
+ raise ArgumentError.new("Name or subdomain not set: #{name}, #{subdomain}")
141
+ end
142
+
143
+ return name, subdomain
144
+ end
145
+
146
+ def collect_hostname
147
+ hostname = @hostname
148
+
149
+ if hostname == LiveTribe::Debut::Debutante::USE_ENVIRONMENT
150
+ connection = Excon.new(INSTANCE_METADATA_HOST)
151
+
152
+ if @use_local_hostname
153
+ path = INSTANCE_LOCAL_HOSTNAME_PATH
154
+ else
155
+ path = INSTANCE_PUBLIC_HOSTNAME_PATH
156
+ end
157
+
158
+ metadata = Fog::JSON.decode(connection.get(:path => path, :expects => 200).body)
159
+
160
+ hostname = metadata['hostname']
161
+ end
162
+
163
+ hostname
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright 2013 the original author or authors
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing,
11
+ # software distributed under the License is distributed on an
12
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ # KIND, either express or implied. See the License for the
14
+ # specific language governing permissions and limitations
15
+ # under the License.
16
+ #
17
+
18
+ module Debut
19
+ VERSION = '0.0.1'
20
+ end
data/lib/debut.rb ADDED
@@ -0,0 +1,105 @@
1
+ #
2
+ # Copyright 2013 the original author or authors
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing,
11
+ # software distributed under the License is distributed on an
12
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13
+ # KIND, either express or implied. See the License for the
14
+ # specific language governing permissions and limitations
15
+ # under the License.
16
+ #
17
+
18
+ require 'debut/version'
19
+
20
+ module LiveTribe
21
+ module Debut
22
+
23
+ class Debutante
24
+
25
+ USE_ENVIRONMENT = '<use environment>'
26
+ USE_LOCAL_HOSTNAME = true
27
+
28
+ def initialize(attributes)
29
+ provider = attributes[:provider].to_s.downcase.to_sym
30
+ begin
31
+ require "debut/#{provider}"
32
+ if LiveTribe::Debut.providers.include?(provider)
33
+ @provider = LiveTribe::Debut.providers[provider].new(attributes)
34
+ else
35
+ raise ArgumentError.new("#{provider} is not a recognized debut provider")
36
+ end
37
+ rescue LoadError
38
+ raise ArgumentError.new("#{provider} is not a recognized debut provider")
39
+ end
40
+
41
+ @provider.use_local_hostname = USE_LOCAL_HOSTNAME
42
+ end
43
+
44
+ def hostname
45
+ @provider.hostname
46
+ end
47
+
48
+ def hostname=(hostname)
49
+ @provider.hostname = hostname
50
+ end
51
+
52
+ def name
53
+ @provider.name
54
+ end
55
+
56
+ def name=(name)
57
+ @provider.name = name
58
+ end
59
+
60
+ def subdomain
61
+ @provider.subdomain
62
+ end
63
+
64
+ def subdomain=(subdomain)
65
+ @provider.subdomain = subdomain
66
+ end
67
+
68
+ def use_local_hostname
69
+ @provider.use_local_hostname
70
+ end
71
+
72
+ def use_local_hostname=(use_local_hostname)
73
+ @provider.use_local_hostname = use_local_hostname
74
+ end
75
+
76
+ def hello
77
+ @provider.hello
78
+ end
79
+
80
+ def goodbye
81
+ @provider.goodbye
82
+ end
83
+
84
+ def to_s
85
+ "#{@provider.name}.#{@provider.subdomain}:#{@provider.to_s}"
86
+ end
87
+ end
88
+
89
+ def self.providers
90
+ @providers ||= {}
91
+ end
92
+
93
+ def self.providers=(new_providers)
94
+ @providers = new_providers
95
+ end
96
+
97
+ class Provider
98
+ def Provider.inherited(clazz)
99
+ provider = clazz.to_s.split('::').last
100
+ LiveTribe::Debut.providers[provider.downcase.to_sym] = clazz
101
+ end
102
+ end
103
+
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: debut
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - LiveTribe - Systems Management Project
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fog
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: gli
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '2.7'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '2.7'
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: A simple way to register your cloud instance with DNS and other lookup
79
+ services
80
+ email: dev@livetribe.codehaus.org
81
+ executables:
82
+ - debut
83
+ extensions: []
84
+ extra_rdoc_files:
85
+ - README.md
86
+ files:
87
+ - bin/debut
88
+ - lib/debut/aws.rb
89
+ - lib/debut/version.rb
90
+ - lib/debut.rb
91
+ - README.md
92
+ homepage: http://www.livetribe.org
93
+ licenses:
94
+ - ASL-2
95
+ post_install_message:
96
+ rdoc_options:
97
+ - --charset=UTF-8
98
+ require_paths:
99
+ - lib
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 1.8.23
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: A simple way to register your cloud instance
119
+ test_files: []
120
+ has_rdoc: