debut 0.0.1

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.
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: