vagrant-orchestrate 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/README.md +89 -2
- data/lib/vagrant-orchestrate/command/init.rb +52 -26
- data/lib/vagrant-orchestrate/plugin.rb +46 -4
- data/lib/vagrant-orchestrate/version.rb +1 -1
- data/spec/vagrant-orchestrate/command/init_spec.rb +18 -0
- data/templates/environment/servers.json.erb +11 -0
- data/templates/vagrant/Vagrantfile.erb +4 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b77cd8446da22ec260eeafa76cfeca730ead095
|
4
|
+
data.tar.gz: ea87fb3abb6f6431d4e059a0e7712dce4bb567c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13bc391116a4a4a528182801220960e560a563b510fde0949073d0320f9424af19507f6d99d2b0ada3875cc18c0db6d6bc774728faa853903b8c8d20745d5532
|
7
|
+
data.tar.gz: 31cba2e18c9f6262b564b671bdb77067398585089530057e01884e57f6a207a6aedb2557464f3c70a6cdf1ee032d3aadebaae8af6fed2235cb5a3c71e24325d2
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -83,8 +83,9 @@ line with `--ssh-username` and `--ssh-private-key-path`. The first line of the f
|
|
83
83
|
managed servers that the `push` command will operate on.
|
84
84
|
|
85
85
|
```ruby
|
86
|
-
managed_servers = %w( myserver1.mydomain.com myserver2.mydomain.com )
|
86
|
+
managed_servers = %w( myserver1.mydomain.com myserver2.mydomain.com )
|
87
87
|
```
|
88
|
+
#### Windows
|
88
89
|
|
89
90
|
This works for Windows managed servers using WinRM as well
|
90
91
|
|
@@ -101,12 +102,98 @@ This works for Windows managed servers using WinRM as well
|
|
101
102
|
config.winrm.transport = :sspinegotiate
|
102
103
|
```
|
103
104
|
|
105
|
+
#### Plugins
|
106
|
+
|
104
107
|
This also supports a self-contained way to install plugins, just list them in the required_plugins section
|
105
108
|
|
106
109
|
```ruby
|
107
110
|
required_plugins = %w( vagrant-managed-servers vagrant-hostsupdater )
|
108
111
|
```
|
109
112
|
|
113
|
+
#### Working with multiple environments
|
114
|
+
It is a very common pattern in software development to have separate environments - e.g. dev, test, and prod.
|
115
|
+
Vagrant Orchestrate offers a way to manage multiple environments using a combination of a single servers.json
|
116
|
+
file and the name of the current git branch to know which the current environment is.
|
117
|
+
|
118
|
+
```javascript
|
119
|
+
# servers.json
|
120
|
+
{
|
121
|
+
"environments": {
|
122
|
+
"dev": {
|
123
|
+
"servers": [
|
124
|
+
"dev.myapp.mydomain.com"
|
125
|
+
]
|
126
|
+
},
|
127
|
+
"test": {
|
128
|
+
"servers": [
|
129
|
+
"test1.myapp.mydomain.com",
|
130
|
+
"test2.myapp.mydomain.com"
|
131
|
+
]
|
132
|
+
},
|
133
|
+
"prod": {
|
134
|
+
"servers": [
|
135
|
+
"prod1.myapp.mydomain.com",
|
136
|
+
"prod2.myapp.mydomain.com",
|
137
|
+
"prod3.myapp.mydomain.com"
|
138
|
+
]
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
```
|
143
|
+
|
144
|
+
Add the following line to the top of your `Vagrantfile`
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
managed_servers = VagrantPlugins::Orchestrate::Plugin.load_servers_for_branch
|
148
|
+
```
|
149
|
+
|
150
|
+
If you create git branches named `dev`, `test`, and `prod`, your vagrantfile will become environment aware and
|
151
|
+
you'll only be able to see the servers appropriate for that environment.
|
152
|
+
|
153
|
+
```
|
154
|
+
$ git branch
|
155
|
+
* dev
|
156
|
+
test
|
157
|
+
prod
|
158
|
+
$ vagrant status
|
159
|
+
Current machine states:
|
160
|
+
|
161
|
+
local not created (virtualbox)
|
162
|
+
dev.myapp.mydomain.com not created (managed)
|
163
|
+
|
164
|
+
$ git checkout test
|
165
|
+
Switched to branch 'test'
|
166
|
+
$ vagrant status
|
167
|
+
Current machine states:
|
168
|
+
|
169
|
+
local not created (virtualbox)
|
170
|
+
test1.myapp.mydomain.com not created (managed)
|
171
|
+
test2.myapp.mydomain.com not created (managed)
|
172
|
+
|
173
|
+
$ git checkout prod
|
174
|
+
Switched to branch 'prod'
|
175
|
+
$ vagrant status
|
176
|
+
Current machine states:
|
177
|
+
|
178
|
+
local not created (virtualbox)
|
179
|
+
prod1.myapp.mydomain.com not created (managed)
|
180
|
+
prod2.myapp.mydomain.com not created (managed)
|
181
|
+
prod3.myapp.mydomain.com not created (managed)
|
182
|
+
```
|
183
|
+
|
184
|
+
Any branch that doesn't have a matching environment in the servers.json file will
|
185
|
+
not list any managed servers.
|
186
|
+
|
187
|
+
```
|
188
|
+
$ git checkout -b my_feature_branch
|
189
|
+
Switched to a new branch 'my_feature_branch'
|
190
|
+
$ vagrant status
|
191
|
+
Current machine states:
|
192
|
+
|
193
|
+
local not created (virtualbox)
|
194
|
+
```
|
195
|
+
#### Puppet
|
196
|
+
|
110
197
|
Experimental puppet templating support is available as well with the `--puppet` flag and associated options
|
111
198
|
|
112
199
|
```ruby
|
@@ -150,7 +237,7 @@ You can run vagrant with increased verbosity if you run into problems
|
|
150
237
|
$ vagrant orchestrate push --debug
|
151
238
|
|
152
239
|
## Filtering managed commands
|
153
|
-
It can be easy to make mistakes such as rebooting production if you have managed long-lived servers as well as local VMs defined in your Vagrantfile. We add some protection with the `orchestrate.filter_managed_commands` configuration setting, which will cause up, provision, reload, and destroy commands to be ignored for servers with the managed provider.
|
240
|
+
It can be easy to make mistakes such as rebooting production if you have managed long-lived servers as well as local VMs defined in your Vagrantfile. We add some protection with the `orchestrate.filter_managed_commands` configuration setting, which will cause up, provision, reload, and destroy commands to be ignored for servers with the managed provider.
|
154
241
|
|
155
242
|
```ruby
|
156
243
|
config.orchestrate.filter_managed_commands = true
|
@@ -15,12 +15,13 @@ module VagrantPlugins
|
|
15
15
|
DEFAULT_SSH_PRIVATE_KEY_PATH = "{{YOUR_SSH_PRIVATE_KEY_PATH}}"
|
16
16
|
DEFAULT_PLUGINS = ["vagrant-managed-servers"]
|
17
17
|
|
18
|
-
# rubocop:disable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity
|
18
|
+
# rubocop:disable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
19
19
|
def execute
|
20
20
|
options = {}
|
21
21
|
|
22
22
|
options[:provisioners] = []
|
23
23
|
options[:servers] = []
|
24
|
+
options[:environments] = []
|
24
25
|
options[:plugins] = DEFAULT_PLUGINS
|
25
26
|
options[:puppet_librarian_puppet] = true
|
26
27
|
options[:puppet_hiera] = true
|
@@ -90,10 +91,14 @@ module VagrantPlugins
|
|
90
91
|
options[:plugins] += p
|
91
92
|
end
|
92
93
|
|
93
|
-
o.on("--servers x,y,z", Array, "A
|
94
|
+
o.on("--servers x,y,z", Array, "A CSV list of FQDNs to target managed servers") do |list|
|
94
95
|
options[:servers] = list
|
95
96
|
end
|
96
97
|
|
98
|
+
o.on("--environments x,y,z", Array, "A CSV list of environments. Takes precedence over --servers") do |list|
|
99
|
+
options[:environments] = list
|
100
|
+
end
|
101
|
+
|
97
102
|
o.on("-f", "--force", "Force overwriting of files") do
|
98
103
|
options[:force] = true
|
99
104
|
end
|
@@ -102,29 +107,8 @@ module VagrantPlugins
|
|
102
107
|
argv = parse_options(opts)
|
103
108
|
return unless argv
|
104
109
|
|
105
|
-
|
106
|
-
|
107
|
-
if options[:puppet_librarian_puppet]
|
108
|
-
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/Puppetfile"))
|
109
|
-
write_file File.join("puppet", "Puppetfile"), contents, options
|
110
|
-
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "modules"))
|
111
|
-
write_file(File.join(@env.cwd, "puppet", "modules", ".gitignore"), "*", options)
|
112
|
-
options[:plugins] << "vagrant-librarian-puppet"
|
113
|
-
end
|
114
|
-
|
115
|
-
if options[:puppet_hiera]
|
116
|
-
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/hiera.yaml"))
|
117
|
-
write_file(File.join("puppet", "hiera.yaml"), contents, options)
|
118
|
-
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "hieradata"))
|
119
|
-
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/hiera/common.yaml"))
|
120
|
-
write_file(File.join(@env.cwd, "puppet", "hieradata", "common.yaml"), contents, options)
|
121
|
-
end
|
122
|
-
|
123
|
-
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "manifests"))
|
124
|
-
write_file(File.join(@env.cwd, "puppet", "manifests", "default.pp"),
|
125
|
-
"# Your puppet code goes here",
|
126
|
-
options)
|
127
|
-
end
|
110
|
+
init_puppet options
|
111
|
+
init_environments options
|
128
112
|
|
129
113
|
options[:shell_paths] ||= options[:shell_inline] ? [] : [DEFAULT_SHELL_PATH]
|
130
114
|
options[:winrm_username] ||= DEFAULT_WINRM_USERNAME
|
@@ -146,6 +130,7 @@ module VagrantPlugins
|
|
146
130
|
ssh_password: options[:ssh_password],
|
147
131
|
ssh_private_key_path: options[:ssh_private_key_path],
|
148
132
|
servers: options[:servers],
|
133
|
+
environments: options[:environments],
|
149
134
|
plugins: options[:plugins]
|
150
135
|
)
|
151
136
|
write_file("Vagrantfile", contents, options)
|
@@ -156,10 +141,51 @@ module VagrantPlugins
|
|
156
141
|
# Success, exit status 0
|
157
142
|
0
|
158
143
|
end
|
159
|
-
# rubocop:enable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity
|
144
|
+
# rubocop:enable Metrics/AbcSize, MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
160
145
|
|
161
146
|
private
|
162
147
|
|
148
|
+
def init_puppet(options)
|
149
|
+
return unless options[:provisioners].include? "puppet"
|
150
|
+
|
151
|
+
FileUtils.mkdir_p(File.join(@env.cwd, "puppet"))
|
152
|
+
if options[:puppet_librarian_puppet]
|
153
|
+
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/Puppetfile"))
|
154
|
+
write_file File.join("puppet", "Puppetfile"), contents, options
|
155
|
+
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "modules"))
|
156
|
+
write_file(File.join(@env.cwd, "puppet", "modules", ".gitignore"), "*", options)
|
157
|
+
options[:plugins] << "vagrant-librarian-puppet"
|
158
|
+
end
|
159
|
+
|
160
|
+
if options[:puppet_hiera]
|
161
|
+
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/hiera.yaml"))
|
162
|
+
write_file(File.join("puppet", "hiera.yaml"), contents, options)
|
163
|
+
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "hieradata"))
|
164
|
+
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/puppet/hiera/common.yaml"))
|
165
|
+
write_file(File.join(@env.cwd, "puppet", "hieradata", "common.yaml"), contents, options)
|
166
|
+
end
|
167
|
+
|
168
|
+
FileUtils.mkdir_p(File.join(@env.cwd, "puppet", "manifests"))
|
169
|
+
write_file(File.join(@env.cwd, "puppet", "manifests", "default.pp"),
|
170
|
+
"# Your puppet code goes here", options)
|
171
|
+
end
|
172
|
+
|
173
|
+
def init_environments(options)
|
174
|
+
environments = options[:environments]
|
175
|
+
return unless environments.any?
|
176
|
+
|
177
|
+
contents = TemplateRenderer.render(Orchestrate.source_root.join("templates/environment/servers.json"),
|
178
|
+
environments: environments)
|
179
|
+
write_file("servers.json", contents, options)
|
180
|
+
@env.ui.info("You've created an environment aware configuration.")
|
181
|
+
@env.ui.info("To complete the process you need to do the following: ")
|
182
|
+
@env.ui.info(" 1. Add the target servers to servers.json")
|
183
|
+
@env.ui.info(" 2. Create a git branch for each environment")
|
184
|
+
environments.each do |env|
|
185
|
+
@env.ui.info(" git branch #{env}")
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
163
189
|
def write_file(filename, contents, options)
|
164
190
|
save_path = Pathname.new(filename).expand_path(@env.cwd)
|
165
191
|
save_path.delete if save_path.exist? && options[:force]
|
@@ -76,11 +76,53 @@ module VagrantPlugins
|
|
76
76
|
|
77
77
|
# Set the logging level on all "vagrant" namespaced
|
78
78
|
# logs as long as we have a valid level.
|
79
|
-
|
80
|
-
Log4r::
|
81
|
-
|
82
|
-
|
79
|
+
@logger = Log4r::Logger.new("vagrant_orchestrate").tap do |logger|
|
80
|
+
logger.outputters = Log4r::Outputter.stderr
|
81
|
+
logger.level = level || 6
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.read_git_branch
|
86
|
+
@logger.debug("Reading git branch")
|
87
|
+
if ENV["GIT_BRANCH"]
|
88
|
+
git_branch = ENV["GIT_BRANCH"]
|
89
|
+
@logger.debug("Read git branch #{git_branch} from GIT_BRANCH environment variable")
|
90
|
+
else
|
91
|
+
command = "git rev-parse --abbrev-ref HEAD"
|
92
|
+
git_branch = `#{command}`.chomp
|
93
|
+
if git_branch.include? "fatal"
|
94
|
+
@logger.error("Unable to determine git branch `#{command}`. Is this a git repo?")
|
95
|
+
git_branch = nil
|
96
|
+
else
|
97
|
+
@logger.debug("Read git branch #{git_branch} using `#{command}`")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
git_branch
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.load_servers_for_branch
|
104
|
+
setup_logging
|
105
|
+
|
106
|
+
git_branch = read_git_branch
|
107
|
+
return [] if git_branch.nil?
|
108
|
+
|
109
|
+
begin
|
110
|
+
fail "servers.json not found" unless File.exist?("servers.json")
|
111
|
+
@logger.debug("Reading servers.json")
|
112
|
+
contents = IO.read("servers.json")
|
113
|
+
@logger.debug("Read servers.json:\n: #{contents}")
|
114
|
+
|
115
|
+
environments = JSON.parse(contents)["environments"]
|
116
|
+
if environments.key? git_branch
|
117
|
+
return environments[git_branch]["servers"]
|
118
|
+
else
|
119
|
+
@logger.info("No environment found for #{git_branch}, no servers loaded.")
|
120
|
+
return []
|
83
121
|
end
|
122
|
+
rescue StandardError => ex
|
123
|
+
# Don't break the user's whole vagrantfile if we can't load the environment
|
124
|
+
@logger.error(ex.message)
|
125
|
+
return []
|
84
126
|
end
|
85
127
|
end
|
86
128
|
end
|
@@ -277,6 +277,24 @@ describe VagrantPlugins::Orchestrate::Command::Init do
|
|
277
277
|
end
|
278
278
|
end
|
279
279
|
|
280
|
+
context "environments" do
|
281
|
+
let(:argv) { ["--environments", "a,b,c"] }
|
282
|
+
describe "vagrantfile" do
|
283
|
+
it "should contain the loading code" do
|
284
|
+
subject.execute
|
285
|
+
vagrantfile = File.readlines(File.join(iso_env.cwd, "Vagrantfile")).join
|
286
|
+
expect(vagrantfile).to include("managed_servers = VagrantPlugins::Orchestrate::Plugin.load_servers_for_branch")
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "servers.json" do
|
291
|
+
it "should exist in the target directory" do
|
292
|
+
subject.execute
|
293
|
+
expect(Dir.entries(iso_env.cwd)).to include("servers.json")
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
280
298
|
context "box" do
|
281
299
|
describe "dummy.box" do
|
282
300
|
it "winds up in the target directory" do
|
@@ -1,4 +1,8 @@
|
|
1
|
+
<% if environments.any? -%>
|
2
|
+
managed_servers = VagrantPlugins::Orchestrate::Plugin.load_servers_for_branch
|
3
|
+
<% else -%>
|
1
4
|
managed_servers = %w( <% servers.each do |s| -%><%= s %> <% end -%>)
|
5
|
+
<% end -%>
|
2
6
|
|
3
7
|
<% if plugins.any? -%>
|
4
8
|
required_plugins = %w( <% plugins.each do |p| -%><%= p %> <% end -%>)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-orchestrate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Baldauf
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- spec/spec_helper.rb
|
94
94
|
- spec/vagrant-orchestrate/command/init_spec.rb
|
95
95
|
- spec/vagrant-orchestrate/command/root_spec.rb
|
96
|
+
- templates/environment/servers.json.erb
|
96
97
|
- templates/puppet/Puppetfile.erb
|
97
98
|
- templates/puppet/hiera.yaml.erb
|
98
99
|
- templates/puppet/hiera/common.yaml.erb
|