engineyard-dns 0.4.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.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/ChangeLog.md +29 -0
- data/Gemfile +4 -0
- data/README.md +106 -0
- data/Rakefile +24 -0
- data/bin/ey-dns +17 -0
- data/engineyard-dns.gemspec +35 -0
- data/features/assign_dns_to_environment.feature +74 -0
- data/features/assign_dns_to_environment_via_different_dns_providers.feature +26 -0
- data/features/step_definitions/common_steps.rb +175 -0
- data/features/step_definitions/dnsimple_steps.rb +9 -0
- data/features/step_definitions/ey_api_steps.rb +15 -0
- data/features/step_definitions/fog_steps.rb +7 -0
- data/features/support/common.rb +29 -0
- data/features/support/engineyard.rb +24 -0
- data/features/support/env.rb +21 -0
- data/features/support/fog_helpers.rb +26 -0
- data/features/support/matchers.rb +11 -0
- data/lib/engineyard-dns.rb +5 -0
- data/lib/engineyard-dns/cli.rb +166 -0
- data/lib/engineyard-dns/version.rb +5 -0
- data/posts/engineyard-2011-05-24.md +34 -0
- data/spec/spec_helper.rb +11 -0
- metadata +223 -0
data/.rspec
ADDED
data/ChangeLog.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# ChangeLog
|
2
|
+
|
3
|
+
## v0.4.0 - 2011/5/23
|
4
|
+
|
5
|
+
* supporting many DNS providers via fog
|
6
|
+
* automatic discovery of which DNS provider hosts your domain
|
7
|
+
* see README for setting up fog credentials
|
8
|
+
|
9
|
+
## v0.3.0 - 2011/5/22
|
10
|
+
|
11
|
+
* ey-dns assign DOMAIN NAME - can pass a subdomain name (only that record is created)
|
12
|
+
|
13
|
+
## v0.2.0 - 2011/5/22
|
14
|
+
|
15
|
+
* If [domain, name] pair already exists then prompt for override
|
16
|
+
|
17
|
+
## v0.1.2 - 2011/5/22
|
18
|
+
|
19
|
+
* Cucumber scenario is now working against http://test.dnsimple.com
|
20
|
+
* Worth rereleasing gem just to celebrate
|
21
|
+
|
22
|
+
## v0.1.1 - 2011/5/22
|
23
|
+
|
24
|
+
* Create .myapp.com and www.myapp.com A records
|
25
|
+
|
26
|
+
## v0.1.0 - 2011/5/22
|
27
|
+
|
28
|
+
* Initial release
|
29
|
+
* Basic implementation of `ey-dns assign DOMAIN`
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Simple DNS for Engine Yard AppCloud environments
|
2
|
+
|
3
|
+
Currently creates A records for a domain (.myapp.com and www.myapp.com) to
|
4
|
+
point to the public IP of an AppCloud environment.
|
5
|
+
|
6
|
+
You can use any DNS provider supported by fog, including AWS Route 53, Blue Box, DNSimple, Linode, Slicehost and Zerigo.
|
7
|
+
|
8
|
+
For example:
|
9
|
+
|
10
|
+
<img src="https://img.skitch.com/20110523-x5mhutfr8r79parhuq7r44sqma.png">
|
11
|
+
|
12
|
+
NOTE: This image is an artist's impression. Probably an artist who doesn't know how
|
13
|
+
HTTP requests and DNS work. HTTP reqests don't go through DNSimple (or any DNS nameserver).
|
14
|
+
The host in the URL is translated from myapp.com into an IP address (e.g. 1.2.3.4) by DNS.
|
15
|
+
The HTTP request then goes to the IP address. But the picture looks nice.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
First, setup DNS credentials in `~/.fog` (see below).
|
20
|
+
|
21
|
+
Basic usage is very simple. Assuming you have registered `myapp.com`
|
22
|
+
with one of your DNS providers, the following will automatically work:
|
23
|
+
|
24
|
+
$ ey-dns assign myapp.com
|
25
|
+
Found AppCloud environment giblets on account main with IP 1.2.3.4
|
26
|
+
Found myapp.com in DNSimple account
|
27
|
+
|
28
|
+
Assigning myapp.com --> 1.2.3.4 (drnic/myapp_production)
|
29
|
+
Assigning www.myapp.com --> 1.2.3.4 (drnic/myapp_production)
|
30
|
+
|
31
|
+
If an AppCloud environment cannot be automatically detected, explicitly pass -e or -a flags
|
32
|
+
like the `ey` CLI itself:
|
33
|
+
|
34
|
+
$ ey-dns assign myapp.com -e myapp_production
|
35
|
+
|
36
|
+
If .myapp.com or www.myapp.com already exist you will be prompted to override them.
|
37
|
+
You can force the override with the `--override` or `-o` flag.
|
38
|
+
|
39
|
+
## Setup
|
40
|
+
|
41
|
+
$ gem install engineyard-dns
|
42
|
+
|
43
|
+
To setup credentials for AppCloud, run the following command for the first time and
|
44
|
+
you will be prompted for credentials:
|
45
|
+
|
46
|
+
$ ey environments --all
|
47
|
+
|
48
|
+
To setup credentials for DNSimple, create a file `~/.fog` to look like:
|
49
|
+
|
50
|
+
:default:
|
51
|
+
:dnsimple_email: EMAIL
|
52
|
+
:dnsimple_password: PASSWORD
|
53
|
+
|
54
|
+
To setup credentials for AWS Route 53, create a file `~/.fog` to look like:
|
55
|
+
|
56
|
+
:default:
|
57
|
+
:aws_access_key_id: ACCESS_KEY
|
58
|
+
:aws_secret_access_key: SECRET_ACCESS_KEY
|
59
|
+
|
60
|
+
If you have multiple DNS providers then add as many credentials within `:default`
|
61
|
+
as you like.
|
62
|
+
|
63
|
+
On Unix, make this file readable to you only:
|
64
|
+
|
65
|
+
$ chmod 600 ~/.fog
|
66
|
+
|
67
|
+
Test you have fog working with your DNS provider:
|
68
|
+
|
69
|
+
$ fog
|
70
|
+
>> provider = 'DNSimple' # or 'AWS' or 'Slicehost' etc
|
71
|
+
>> Fog::DNS.new({:provider => provider}).zones.all.map(&:domain)
|
72
|
+
["drnicwilliams.com", "emrubyconf.com", ...]
|
73
|
+
|
74
|
+
|
75
|
+
## Development
|
76
|
+
|
77
|
+
[](http://travis-ci.org/engineyard/engineyard-dns)
|
78
|
+
|
79
|
+
The test suite is purely cucumber scenarios. No rspec tests are being used. There are credentials for http://test.dnsimple.com built into the test suite. You should not have to do anything to run the tests except:
|
80
|
+
|
81
|
+
git clone git://github.com/engineyard/engineyard-dns.git
|
82
|
+
cd engineyard-dns
|
83
|
+
bundle
|
84
|
+
bundle exec rake
|
85
|
+
|
86
|
+
## License
|
87
|
+
|
88
|
+
Copyright (c) 2010 Engine Yard, Inc
|
89
|
+
|
90
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
91
|
+
of this software and associated documentation files (the "Software"), to deal
|
92
|
+
in the Software without restriction, including without limitation the rights
|
93
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
94
|
+
copies of the Software, and to permit persons to whom the Software is
|
95
|
+
furnished to do so, subject to the following conditions:
|
96
|
+
|
97
|
+
The above copyright notice and this permission notice shall be included in
|
98
|
+
all copies or substantial portions of the Software.
|
99
|
+
|
100
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
101
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
102
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
103
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
104
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
105
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
106
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
desc "Run all examples"
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
namespace :cucumber do
|
10
|
+
require 'cucumber/rake/task'
|
11
|
+
Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
|
12
|
+
t.cucumber_opts = "--tags @wip"
|
13
|
+
end
|
14
|
+
Cucumber::Rake::Task.new(:ok, 'Run features that should be working') do |t|
|
15
|
+
t.cucumber_opts = "--tags ~@wip"
|
16
|
+
end
|
17
|
+
task :all => [:ok, :wip]
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Alias for cucumber:ok'
|
21
|
+
task :cucumber => 'cucumber:ok'
|
22
|
+
|
23
|
+
desc "Specs and Cucumber features by default"
|
24
|
+
task :default => ["spec", "cucumber"]
|
data/bin/ey-dns
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
4
|
+
require 'engineyard-dns'
|
5
|
+
require 'engineyard-dns/cli'
|
6
|
+
|
7
|
+
begin
|
8
|
+
EngineYard::DNS::CLI.start
|
9
|
+
rescue EY::Error => e
|
10
|
+
EY.ui.print_exception(e)
|
11
|
+
exit(1)
|
12
|
+
rescue Interrupt => e
|
13
|
+
puts
|
14
|
+
EY.ui.print_exception(e)
|
15
|
+
EY.ui.say("Quitting...")
|
16
|
+
exit(1)
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "engineyard-dns/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "engineyard-dns"
|
7
|
+
s.version = EngineYard::DNS::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Dr Nic Williams"]
|
10
|
+
s.email = ["drnicwilliams@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/engineyard/engineyard-dns#readme"
|
12
|
+
s.summary = %q{Configure your Engine Yard AppCloud environment and your DNSimple domain.}
|
13
|
+
s.description = %q{Easily configure your DNS with Engine Yard AppCloud via DNSimple.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "engineyard-dns"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency("thor")
|
23
|
+
s.add_dependency("engineyard")
|
24
|
+
s.add_dependency("fog")
|
25
|
+
|
26
|
+
s.add_development_dependency("rake", ["~> 0.9.0"])
|
27
|
+
s.add_development_dependency("cucumber", ["~> 0.10"])
|
28
|
+
s.add_development_dependency("rspec", ["~> 2.5"])
|
29
|
+
s.add_development_dependency("json", ["~>1.4.0"])
|
30
|
+
s.add_development_dependency("awesome_print")
|
31
|
+
s.add_development_dependency("realweb", '~>0.1.6')
|
32
|
+
s.add_development_dependency("open4")
|
33
|
+
s.add_development_dependency("sinatra")
|
34
|
+
s.add_development_dependency("fakeweb", "~>1.3.0")
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Feature: Assign DNS to environment IP address via DNSimple
|
2
|
+
I want to assign DNS record to an AppCloud environment IP address
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given I have setup my engineyard email/password for API access
|
6
|
+
And I have "two apps" in AppCloud
|
7
|
+
And I have setup my fog credentials for "DNSimple"
|
8
|
+
And I have DNS domain "myapp.com" with provider "DNSimple"
|
9
|
+
|
10
|
+
Scenario: Assign new DNS A Record to an environment
|
11
|
+
When I run local executable "ey-dns" with arguments "assign myapp.com --account main --environment giblets"
|
12
|
+
Then I should see exactly
|
13
|
+
"""
|
14
|
+
Fetching AppCloud environment information...
|
15
|
+
Found AppCloud environment giblets on account main with IP 174.129.7.113
|
16
|
+
|
17
|
+
Searching for myapp.com amongst your DNS providers...
|
18
|
+
Found myapp.com in DNSimple account
|
19
|
+
|
20
|
+
Assigning myapp.com --> 174.129.7.113 (main/giblets)
|
21
|
+
Created A record for myapp.com
|
22
|
+
Assigning www.myapp.com --> 174.129.7.113 (main/giblets)
|
23
|
+
Created A record for www.myapp.com
|
24
|
+
Complete!
|
25
|
+
|
26
|
+
"""
|
27
|
+
# Found 2 records for myapp.com
|
28
|
+
# .myapp.com (A)-> 174.129.7.113 (ttl:60, id:\d+)
|
29
|
+
# www.myapp.com (A)-> 174.129.7.113 (ttl:60, id:\d+)
|
30
|
+
|
31
|
+
Scenario: Resssign DNS A Record to an environment
|
32
|
+
When I run local executable "ey-dns" with arguments "assign myapp.com --account main --environment giblets"
|
33
|
+
And I run local executable "ey-dns" with arguments "assign myapp.com --account main --environment giblets --override"
|
34
|
+
Then I should see matching
|
35
|
+
"""
|
36
|
+
Fetching AppCloud environment information...
|
37
|
+
Found AppCloud environment giblets on account main with IP 174.129.7.113
|
38
|
+
|
39
|
+
Searching for myapp.com amongst your DNS providers...
|
40
|
+
Found myapp.com in DNSimple account
|
41
|
+
|
42
|
+
Deleted myapp.com
|
43
|
+
Assigning myapp.com --> 174.129.7.113 (main/giblets)
|
44
|
+
Created A record for myapp.com
|
45
|
+
Deleted www.myapp.com
|
46
|
+
Assigning www.myapp.com --> 174.129.7.113 (main/giblets)
|
47
|
+
Created A record for www.myapp.com
|
48
|
+
Complete!
|
49
|
+
|
50
|
+
"""
|
51
|
+
# Found 2 records for myapp.com
|
52
|
+
# .myapp.com (A)-> 174.129.7.113 (ttl:60, id:\d+)
|
53
|
+
# www.myapp.com (A)-> 174.129.7.113 (ttl:60, id:\d+)
|
54
|
+
|
55
|
+
Scenario: Assign subdomain A Record to an environment
|
56
|
+
When I run local executable "ey-dns" with arguments "assign myapp.com staging --account main --environment giblets"
|
57
|
+
Then I should see exactly
|
58
|
+
"""
|
59
|
+
Fetching AppCloud environment information...
|
60
|
+
Found AppCloud environment giblets on account main with IP 174.129.7.113
|
61
|
+
|
62
|
+
Searching for myapp.com amongst your DNS providers...
|
63
|
+
Found myapp.com in DNSimple account
|
64
|
+
|
65
|
+
Assigning staging.myapp.com --> 174.129.7.113 (main/giblets)
|
66
|
+
Created A record for staging.myapp.com
|
67
|
+
Complete!
|
68
|
+
|
69
|
+
"""
|
70
|
+
# Found 1 records for myapp.com
|
71
|
+
# staging.myapp.com (A)-> 174.129.7.113 (ttl:60, id:\d+)
|
72
|
+
|
73
|
+
|
74
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: Assign DNS to environment IP address
|
2
|
+
I want to assign DNS record to an AppCloud environment IP address
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given I have setup my engineyard email/password for API access
|
6
|
+
And I have "two apps" in AppCloud
|
7
|
+
|
8
|
+
Scenario: Assign new DNS A Record to an environment via fog to DNSimple
|
9
|
+
Given I have setup my fog credentials for "DNSimple"
|
10
|
+
And I have DNS domain "myapp.com" with provider "DNSimple"
|
11
|
+
When I run local executable "ey-dns" with arguments "assign myapp.com --account main --environment giblets"
|
12
|
+
Then I should see exactly
|
13
|
+
"""
|
14
|
+
Fetching AppCloud environment information...
|
15
|
+
Found AppCloud environment giblets on account main with IP 174.129.7.113
|
16
|
+
|
17
|
+
Searching for myapp.com amongst your DNS providers...
|
18
|
+
Found myapp.com in DNSimple account
|
19
|
+
|
20
|
+
Assigning myapp.com --> 174.129.7.113 (main/giblets)
|
21
|
+
Created A record for myapp.com
|
22
|
+
Assigning www.myapp.com --> 174.129.7.113 (main/giblets)
|
23
|
+
Created A record for www.myapp.com
|
24
|
+
Complete!
|
25
|
+
|
26
|
+
"""
|
@@ -0,0 +1,175 @@
|
|
1
|
+
Given /^this project is active project folder/ do
|
2
|
+
@active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^env variable \$([\w_]+) set to "(.*)"/ do |env_var, value|
|
6
|
+
ENV[env_var] = value
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /"(.*)" folder is deleted/ do |folder|
|
10
|
+
in_project_folder { FileUtils.rm_rf folder }
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
|
14
|
+
@stdout = StringIO.new
|
15
|
+
in_project_folder do
|
16
|
+
if Object.const_defined?("APP_ROOT")
|
17
|
+
APP_ROOT.replace(FileUtils.pwd)
|
18
|
+
else
|
19
|
+
APP_ROOT = FileUtils.pwd
|
20
|
+
end
|
21
|
+
run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
|
22
|
+
end
|
23
|
+
File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
|
24
|
+
@stdout.rewind
|
25
|
+
f << @stdout.read
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
30
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
31
|
+
in_project_folder do
|
32
|
+
system "#{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
37
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
38
|
+
in_project_folder do
|
39
|
+
system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
44
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
45
|
+
executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
|
46
|
+
in_project_folder do
|
47
|
+
system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
When /^I invoke task "rake (.*)"/ do |task|
|
52
|
+
@stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
|
53
|
+
in_project_folder do
|
54
|
+
system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Then /^folder "(.*)" (is|is not) created/ do |folder, is|
|
59
|
+
in_project_folder do
|
60
|
+
File.exists?(folder).should(is == 'is' ? be_true : be_false)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Then /^file "(.*)" (is|is not) created/ do |file, is|
|
65
|
+
in_project_folder do
|
66
|
+
File.exists?(file).should(is == 'is' ? be_true : be_false)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
Then /^file with name matching "(.*)" is created/ do |pattern|
|
71
|
+
in_project_folder do
|
72
|
+
Dir[pattern].should_not be_empty
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
|
77
|
+
in_project_folder do
|
78
|
+
actual_output = File.read(file)
|
79
|
+
(does == 'does') ?
|
80
|
+
actual_output.should(match(/#{regex}/)) :
|
81
|
+
actual_output.should_not(match(/#{regex}/))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
|
86
|
+
File.exists?(gem_file).should be_true
|
87
|
+
File.exists?(project_file).should be_true
|
88
|
+
gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
|
89
|
+
project_file_contents = File.read(File.join(@active_project_folder, project_file))
|
90
|
+
project_file_contents.should == gem_file_contents
|
91
|
+
end
|
92
|
+
|
93
|
+
Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
|
94
|
+
actual_output = File.read(@stdout)
|
95
|
+
does_invoke == "does" ?
|
96
|
+
actual_output.should(match(/dependency\s+#{generator}/)) :
|
97
|
+
actual_output.should_not(match(/dependency\s+#{generator}/))
|
98
|
+
end
|
99
|
+
|
100
|
+
Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
|
101
|
+
actual_output = File.read(@stdout)
|
102
|
+
actual_output.should match(/#{opt1}/)
|
103
|
+
actual_output.should match(/#{opt2}/)
|
104
|
+
end
|
105
|
+
|
106
|
+
Then /^I should see "([^\"]*)"$/ do |text|
|
107
|
+
actual_output = File.read(@stdout)
|
108
|
+
actual_output.should contain(text)
|
109
|
+
end
|
110
|
+
|
111
|
+
Then /^I should see$/ do |text|
|
112
|
+
actual_output = File.read(@stdout)
|
113
|
+
actual_output.should contain(text)
|
114
|
+
end
|
115
|
+
|
116
|
+
Then /^I should not see$/ do |text|
|
117
|
+
actual_output = File.read(@stdout)
|
118
|
+
actual_output.should_not contain(text)
|
119
|
+
end
|
120
|
+
|
121
|
+
Then /^I should see exactly$/ do |text|
|
122
|
+
actual_output = File.read(@stdout)
|
123
|
+
actual_output.should == text
|
124
|
+
end
|
125
|
+
|
126
|
+
Then /^I should see matching$/ do |text|
|
127
|
+
regexp = Regexp.new(text.gsub("(", '\(').gsub(")", '\)'))
|
128
|
+
actual_output = File.read(@stdout)
|
129
|
+
actual_output.should match(regexp)
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
Then /^I should see all (\d+) tests pass/ do |expected_test_count|
|
134
|
+
expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
|
135
|
+
actual_output = File.read(@stdout)
|
136
|
+
actual_output.should match(expected)
|
137
|
+
end
|
138
|
+
|
139
|
+
Then /^I should see all (\d+) examples pass/ do |expected_test_count|
|
140
|
+
expected = %r{^#{expected_test_count} examples?, 0 failures}
|
141
|
+
actual_output = File.read(@stdout)
|
142
|
+
actual_output.should match(expected)
|
143
|
+
end
|
144
|
+
|
145
|
+
Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
|
146
|
+
in_project_folder do
|
147
|
+
yaml = eval yaml
|
148
|
+
YAML.load(File.read(file)).should == yaml
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
Then /^Rakefile can display tasks successfully/ do
|
153
|
+
@stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
|
154
|
+
in_project_folder do
|
155
|
+
system "rake -T > #{@stdout} 2> #{@stdout}"
|
156
|
+
end
|
157
|
+
actual_output = File.read(@stdout)
|
158
|
+
actual_output.should match(/^rake\s+\w+\s+#\s.*/)
|
159
|
+
end
|
160
|
+
|
161
|
+
Then /^task "rake (.*)" is executed successfully/ do |task|
|
162
|
+
@stdout.should_not be_nil
|
163
|
+
actual_output = File.read(@stdout)
|
164
|
+
actual_output.should_not match(/^Don't know how to build task '#{task}'/)
|
165
|
+
actual_output.should_not match(/Error/i)
|
166
|
+
end
|
167
|
+
|
168
|
+
Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
|
169
|
+
in_project_folder do
|
170
|
+
gem_file = Dir["pkg/*.gem"].first
|
171
|
+
gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
|
172
|
+
spec_value = gem_spec.send(key.to_sym)
|
173
|
+
spec_value.to_s.should match(/#{regex}/)
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Given /^I have setup my engineyard email\/password for API access$/ do
|
2
|
+
ENV['EYRC'] = File.join(@home_path, ".eyrc")
|
3
|
+
token = { ENV['CLOUD_URL'] => {
|
4
|
+
"api_token" => "f81a1706ddaeb148cfb6235ddecfc1cf"} }
|
5
|
+
File.open(ENV['EYRC'], "w"){|f| YAML.dump(token, f) }
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^I have "two accounts, two apps, two environments, ambiguous" in AppCloud$/ do
|
9
|
+
api_scenario "two accounts, two apps, two environments, ambiguous"
|
10
|
+
end
|
11
|
+
|
12
|
+
# has a known public IP in its hostname ec2-174-129-7-113.compute-1.amazonaws.com
|
13
|
+
When /^I have "two apps" in AppCloud$/ do
|
14
|
+
api_scenario "two apps"
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CommonHelpers
|
2
|
+
def in_tmp_folder(&block)
|
3
|
+
FileUtils.chdir(@tmp_root, &block)
|
4
|
+
end
|
5
|
+
|
6
|
+
def in_project_folder(&block)
|
7
|
+
project_folder = @active_project_folder || @tmp_root
|
8
|
+
FileUtils.chdir(project_folder, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def in_home_folder(&block)
|
12
|
+
FileUtils.chdir(@home_path, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def force_local_lib_override(project_name = @project_name)
|
16
|
+
rakefile = File.read(File.join(project_name, 'Rakefile'))
|
17
|
+
File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
|
18
|
+
f << "$:.unshift('#{@lib_path}')\n"
|
19
|
+
f << rakefile
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_active_project_folder project_name
|
24
|
+
@active_project_folder = File.join(@tmp_root, project_name)
|
25
|
+
@project_name = project_name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
World(CommonHelpers)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
engineyard_loaded_path = $:.select { |path| path =~ %r|gems/engineyard-\d+| }.first
|
2
|
+
EY_ROOT = engineyard_loaded_path.gsub(%r|/\w+$|,'')
|
3
|
+
|
4
|
+
# helper to be stubbed out from engineyard spec_helper.rb
|
5
|
+
def shared_examples_for(title)
|
6
|
+
end
|
7
|
+
|
8
|
+
support = Dir[File.join(EY_ROOT,'/spec/support/*.rb')]
|
9
|
+
support.each{|helper| require helper }
|
10
|
+
World(Spec::Helpers)
|
11
|
+
|
12
|
+
require "fakeweb"
|
13
|
+
|
14
|
+
Before do
|
15
|
+
ENV["NO_SSH"] = "true"
|
16
|
+
ENV['CLOUD_URL'] = EY.fake_awsm
|
17
|
+
FakeWeb.allow_net_connect = true
|
18
|
+
end
|
19
|
+
|
20
|
+
After do
|
21
|
+
ENV.delete('CLOUD_URL')
|
22
|
+
ENV.delete('EYRC')
|
23
|
+
ENV.delete('NO_SSH')
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'engineyard-dns'
|
4
|
+
require 'dnsimple'
|
5
|
+
require 'dnsimple/cli'
|
6
|
+
require 'fog'
|
7
|
+
|
8
|
+
path = ENV['PATH']
|
9
|
+
|
10
|
+
Before do
|
11
|
+
@tmp_root = File.dirname(__FILE__) + "/../../tmp"
|
12
|
+
@active_project_folder = @tmp_root
|
13
|
+
@home_path = File.expand_path(File.join(@tmp_root, "home"))
|
14
|
+
@lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
15
|
+
@fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
|
16
|
+
FileUtils.rm_rf @tmp_root
|
17
|
+
FileUtils.mkdir_p @home_path
|
18
|
+
ENV['HOME'] = @home_path
|
19
|
+
fixture_bin_path = File.expand_path('../../../fixtures/bin', __FILE__)
|
20
|
+
ENV['PATH'] = fixture_bin_path + ":" + path
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FogHelpers
|
2
|
+
def setup_dns_credentials(provider)
|
3
|
+
email, password = "ossgrants+dns@engineyard.com", "ossgrants1"
|
4
|
+
File.open("#{ENV['HOME']}/.fog", "w") do |file|
|
5
|
+
@credentials = case provider.to_sym
|
6
|
+
when :DNSimple
|
7
|
+
{ :dnsimple_email => email, :dnsimple_password => password}
|
8
|
+
else
|
9
|
+
raise "No credentials available for provider '#{provider}'"
|
10
|
+
end
|
11
|
+
file << YAML::dump(:default => @credentials)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_domain(provider, domain)
|
16
|
+
dns_provider(provider).zones.select { |z| z.domain == domain }.each do |domain|
|
17
|
+
domain.destroy
|
18
|
+
end
|
19
|
+
dns_provider(provider).zones.create(:domain => domain)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dns_provider(provider)
|
23
|
+
@dns_provider ||= Fog::DNS.new({:provider => provider})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
World(FogHelpers)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Matchers
|
2
|
+
def contain(expected)
|
3
|
+
simple_matcher("contain #{expected.inspect}") do |given, matcher|
|
4
|
+
matcher.failure_message = "expected #{given.inspect} to contain #{expected.inspect}"
|
5
|
+
matcher.negative_failure_message = "expected #{given.inspect} not to contain #{expected.inspect}"
|
6
|
+
given.index expected
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
World(Matchers)
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require "engineyard"
|
2
|
+
require "engineyard/thor"
|
3
|
+
require "engineyard/cli"
|
4
|
+
require "engineyard/cli/ui"
|
5
|
+
require "engineyard/error"
|
6
|
+
require "fog"
|
7
|
+
require "fog/bin"
|
8
|
+
|
9
|
+
module EngineYard
|
10
|
+
module DNS
|
11
|
+
class CLI < Thor
|
12
|
+
include EY::UtilityMethods
|
13
|
+
# include Thor::Actions
|
14
|
+
|
15
|
+
def self.start(*)
|
16
|
+
Thor::Base.shell = EY::CLI::UI
|
17
|
+
EY.ui = EY::CLI::UI.new
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
desc "assign DOMAIN [NAME]", "Assign DNS domain/tld (or name.tld) to your AppCloud environment"
|
23
|
+
method_option :verbose, :aliases => ["-V"], :desc => "Display more output"
|
24
|
+
method_option :environment, :aliases => ["-e"], :desc => "Environment in which to deploy this application", :type => :string
|
25
|
+
method_option :account, :aliases => ["-c"], :desc => "Name of the account you want to deploy in"
|
26
|
+
method_option :override, :aliases => ["-o"], :type => :boolean, :desc => "Override DNSimple records if they already exist"
|
27
|
+
def assign(domain_name, name = "")
|
28
|
+
say "Fetching AppCloud environment information..."; $stdout.flush
|
29
|
+
|
30
|
+
environment = fetch_environment(options[:environment], options[:account])
|
31
|
+
account_name, env_name = environment.account.name, environment.name
|
32
|
+
unless environment.instances.first
|
33
|
+
error "Environment #{account_name}/#{env_name} has no booted instances."
|
34
|
+
end
|
35
|
+
public_hostname = environment.instances.first.public_hostname
|
36
|
+
status = environment.instances.first.status
|
37
|
+
|
38
|
+
# TODO - use DNS client to convert public_hostname into IP address
|
39
|
+
unless public_hostname =~ /ec2-(\d+)-(\d+)-(\d+)-(\d+)/
|
40
|
+
error "Cannot determine public IP from current hostname #{public_hostname}"
|
41
|
+
end
|
42
|
+
public_ip = "#{$1}.#{$2}.#{$3}.#{$4}"
|
43
|
+
|
44
|
+
say "Found AppCloud environment #{env_name} on account #{account_name} with IP #{public_ip}"
|
45
|
+
|
46
|
+
say ""
|
47
|
+
say "Searching for #{domain_name} amongst your DNS providers..."; $stdout.flush
|
48
|
+
|
49
|
+
domain, provider_name = find_domain(domain_name)
|
50
|
+
unless domain
|
51
|
+
error "Please register domain #{domain_name} with your DNS provider"
|
52
|
+
end
|
53
|
+
say "Found #{domain_name} in #{provider_name} account"
|
54
|
+
say ""; $stdout.flush
|
55
|
+
|
56
|
+
assign_dns(domain, account_name, env_name, public_ip, name, options[:override])
|
57
|
+
assign_dns(domain, account_name, env_name, public_ip, "www", options[:override]) if name == ""
|
58
|
+
|
59
|
+
say "Complete!", :green
|
60
|
+
|
61
|
+
# ::DNSimple::Commands::ListRecords.new.execute([domain])
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "version", "show version information"
|
65
|
+
def version
|
66
|
+
require 'engineyard-jenkins/version'
|
67
|
+
shell.say Engineyard::Jenkins::VERSION
|
68
|
+
end
|
69
|
+
|
70
|
+
map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
|
71
|
+
|
72
|
+
private
|
73
|
+
def say(msg, color = nil)
|
74
|
+
color ? shell.say(msg, color) : shell.say(msg)
|
75
|
+
end
|
76
|
+
|
77
|
+
def display(text)
|
78
|
+
shell.say text
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
|
82
|
+
def error(text)
|
83
|
+
shell.say "ERROR: #{text}", :red
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
|
87
|
+
def watch_page_while(host, port, path)
|
88
|
+
waiting = true
|
89
|
+
while waiting
|
90
|
+
begin
|
91
|
+
Net::HTTP.start(host, port) do |http|
|
92
|
+
req = http.get(path)
|
93
|
+
waiting = yield req
|
94
|
+
end
|
95
|
+
sleep 1; print '.'; $stdout.flush
|
96
|
+
rescue SocketError => e
|
97
|
+
sleep 1; print 'x'; $stdout.flush
|
98
|
+
rescue Exception => e
|
99
|
+
puts e.message
|
100
|
+
sleep 1; print '.'; $stdout.flush
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Discover which DNS provider (DNSimple, etc) is controlling +domain_name+ (a zone)
|
106
|
+
# and return [domain/zone, provider name]
|
107
|
+
#
|
108
|
+
# TODO remove hard-wiring for dnsimple; and discover which provider hosts domain/zone
|
109
|
+
# TODO how to get provider name (2nd result) from fog's Zone class? (no need to return 2nd arg)
|
110
|
+
def find_domain(domain_name)
|
111
|
+
dns_provider_names.each do |provider|
|
112
|
+
dns_provider = ::Fog::DNS.new({:provider => provider})
|
113
|
+
if domain = dns_provider.zones.select {|z| z.domain == domain_name}.first
|
114
|
+
return [domain, provider]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
[nil, nil]
|
118
|
+
end
|
119
|
+
|
120
|
+
def assign_dns(domain, account_name, env_name, public_ip, name = "", override = false)
|
121
|
+
if record = domain.records.select {|r| r.name == name}.first
|
122
|
+
if override || ask_override_dns?(domain, name)
|
123
|
+
record.destroy
|
124
|
+
say "Deleted #{domain_name domain, name}"
|
125
|
+
else
|
126
|
+
error "Cannot replace existing #{domain_name domain, name} DNS"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
say "Assigning "; say "#{domain_name domain, name} ", :green; say "--> "; say "#{public_ip} ", :green; say "(#{account_name}/#{env_name})"
|
130
|
+
$stdout.flush
|
131
|
+
|
132
|
+
record = domain.records.create(:ip => public_ip, :name => name, :type => "A", :ttl => "60")
|
133
|
+
say "Created A record for #{domain_name domain, name}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def ask_override_dns?(domain, name)
|
137
|
+
ui = EY::CLI::UI::Prompter.backend
|
138
|
+
ui.agree("Replace #{domain_name domain, name}: ", "y")
|
139
|
+
end
|
140
|
+
|
141
|
+
# "myapp.com", "name" => "name.myapp.com"
|
142
|
+
# "myapp.com", "" => "myapp.com"
|
143
|
+
def domain_name(domain, name = nil)
|
144
|
+
if name && name.length > 0
|
145
|
+
"#{name}.#{domain.domain}"
|
146
|
+
else
|
147
|
+
domain.domain
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns the list of DNS providers that the current user has access to
|
152
|
+
# Includes the +fog_dns_providers+ list
|
153
|
+
# TODO find credentials in alternate locations (e.g. ~/.dnsimple)
|
154
|
+
def dns_provider_names
|
155
|
+
fog_dns_provider_names
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the list of DNS providers that the current user has fog credentials
|
159
|
+
# TODO how do I get the base list from fog?
|
160
|
+
def fog_dns_provider_names
|
161
|
+
['AWS', 'Bluebox', 'DNSimple', 'Linode', 'Slicehost', 'Zerigo'] & Fog.providers
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Simple DNS for AppCloud with DNSimple
|
2
|
+
|
3
|
+
For me, one of the things I liked to do with a new AppCloud application is to attached a pretty domain. The default AWS EC2 URL doesn't glorify my fine efforts.
|
4
|
+
|
5
|
+
I've started using the new [DNSimple](http://dnsimple.com/) as my DNS registrar and name server, and I believe an increasing number of AppCloud customers are too.
|
6
|
+
|
7
|
+
To make setting up DNS easier with AppCloud, we've released the `ey-dns` command line application.
|
8
|
+
|
9
|
+
It's really quite easy to use:
|
10
|
+
|
11
|
+
1. Register your application's domain with [DNSimple](http://dnsimple.com/)
|
12
|
+
2. Transfer your domain to DNSimple or change the name servers to ns1.dnsimple.com (ns2, ns3, etc)
|
13
|
+
3. Install and run the command line application:
|
14
|
+
|
15
|
+
$ gem install engineyard-dns
|
16
|
+
$ cd path/to/my/app
|
17
|
+
$ ey-dns apply myapp.com
|
18
|
+
Assigning myapp.com --> 1.2.3.4 (drnic/myapp_production)
|
19
|
+
Assigning www.myapp.com --> 1.2.3.4 (drnic/myapp_production)
|
20
|
+
|
21
|
+
Found 2 records for myapp.com
|
22
|
+
.myapp.com (A)-> 1.2.3.4 (ttl:, id:12345)
|
23
|
+
www.myapp.com (A)-> 1.2.3.4 (ttl:, id:12346)
|
24
|
+
|
25
|
+
If you have previously assigned the domain records to another host, it will prompt you to change them.
|
26
|
+
|
27
|
+
If there is any confusion about which AppCloud environment is hosting your application, it will show you your options and then you can use the `--environment` and `--account` options to be more specific:
|
28
|
+
|
29
|
+
$ ey-dns apply myapp.com --environment myapp_production
|
30
|
+
$ ey-dns apply myapp.com staging --environment myapp_staging
|
31
|
+
|
32
|
+
Hopefully this tool makes it much easier to setup or change DNS for your AppCloud environments. Let us know in the comments or in the project's [Issues](https://github.com/engineyard/engineyard-dns/issues) if you love it, find bugs or have feature requests.
|
33
|
+
|
34
|
+
The source and instructions for the project is [available on GitHub](https://github.com/engineyard/engineyard-dns#readme).
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: engineyard-dns
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.4.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dr Nic Williams
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-23 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: thor
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: engineyard
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: fog
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rake
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.9.0
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: cucumber
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0.10"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rspec
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "2.5"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: json
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.4.0
|
91
|
+
type: :development
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: awesome_print
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id008
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: realweb
|
106
|
+
prerelease: false
|
107
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ~>
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.1.6
|
113
|
+
type: :development
|
114
|
+
version_requirements: *id009
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: open4
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: "0"
|
124
|
+
type: :development
|
125
|
+
version_requirements: *id010
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sinatra
|
128
|
+
prerelease: false
|
129
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: "0"
|
135
|
+
type: :development
|
136
|
+
version_requirements: *id011
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: fakeweb
|
139
|
+
prerelease: false
|
140
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ~>
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.3.0
|
146
|
+
type: :development
|
147
|
+
version_requirements: *id012
|
148
|
+
description: Easily configure your DNS with Engine Yard AppCloud via DNSimple.
|
149
|
+
email:
|
150
|
+
- drnicwilliams@gmail.com
|
151
|
+
executables:
|
152
|
+
- ey-dns
|
153
|
+
extensions: []
|
154
|
+
|
155
|
+
extra_rdoc_files: []
|
156
|
+
|
157
|
+
files:
|
158
|
+
- .gitignore
|
159
|
+
- .rspec
|
160
|
+
- .travis.yml
|
161
|
+
- ChangeLog.md
|
162
|
+
- Gemfile
|
163
|
+
- README.md
|
164
|
+
- Rakefile
|
165
|
+
- bin/ey-dns
|
166
|
+
- engineyard-dns.gemspec
|
167
|
+
- features/assign_dns_to_environment.feature
|
168
|
+
- features/assign_dns_to_environment_via_different_dns_providers.feature
|
169
|
+
- features/step_definitions/common_steps.rb
|
170
|
+
- features/step_definitions/dnsimple_steps.rb
|
171
|
+
- features/step_definitions/ey_api_steps.rb
|
172
|
+
- features/step_definitions/fog_steps.rb
|
173
|
+
- features/support/common.rb
|
174
|
+
- features/support/engineyard.rb
|
175
|
+
- features/support/env.rb
|
176
|
+
- features/support/fog_helpers.rb
|
177
|
+
- features/support/matchers.rb
|
178
|
+
- lib/engineyard-dns.rb
|
179
|
+
- lib/engineyard-dns/cli.rb
|
180
|
+
- lib/engineyard-dns/version.rb
|
181
|
+
- posts/engineyard-2011-05-24.md
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
has_rdoc: true
|
184
|
+
homepage: https://github.com/engineyard/engineyard-dns#readme
|
185
|
+
licenses: []
|
186
|
+
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options: []
|
189
|
+
|
190
|
+
require_paths:
|
191
|
+
- lib
|
192
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ">="
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: "0"
|
198
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
none: false
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: "0"
|
204
|
+
requirements: []
|
205
|
+
|
206
|
+
rubyforge_project: engineyard-dns
|
207
|
+
rubygems_version: 1.6.2
|
208
|
+
signing_key:
|
209
|
+
specification_version: 3
|
210
|
+
summary: Configure your Engine Yard AppCloud environment and your DNSimple domain.
|
211
|
+
test_files:
|
212
|
+
- features/assign_dns_to_environment.feature
|
213
|
+
- features/assign_dns_to_environment_via_different_dns_providers.feature
|
214
|
+
- features/step_definitions/common_steps.rb
|
215
|
+
- features/step_definitions/dnsimple_steps.rb
|
216
|
+
- features/step_definitions/ey_api_steps.rb
|
217
|
+
- features/step_definitions/fog_steps.rb
|
218
|
+
- features/support/common.rb
|
219
|
+
- features/support/engineyard.rb
|
220
|
+
- features/support/env.rb
|
221
|
+
- features/support/fog_helpers.rb
|
222
|
+
- features/support/matchers.rb
|
223
|
+
- spec/spec_helper.rb
|