safety_razor 0.1.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/.cane +0 -0
- data/.gitignore +19 -0
- data/.tailor +4 -0
- data/.travis.yml +11 -0
- data/Berksfile +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +9 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +328 -0
- data/Rakefile +39 -0
- data/Vagrantfile +27 -0
- data/lib/safety_razor.rb +7 -0
- data/lib/safety_razor/client.rb +58 -0
- data/lib/safety_razor/slice/active_model.rb +30 -0
- data/lib/safety_razor/slice/base.rb +89 -0
- data/lib/safety_razor/slice/broker.rb +27 -0
- data/lib/safety_razor/slice/model.rb +27 -0
- data/lib/safety_razor/slice/node.rb +58 -0
- data/lib/safety_razor/slice/policy.rb +27 -0
- data/lib/safety_razor/slice/tag.rb +22 -0
- data/lib/safety_razor/slice/tag_matcher.rb +65 -0
- data/lib/safety_razor/version.rb +6 -0
- data/safety_razor.gemspec +36 -0
- data/script/bootstrap +33 -0
- data/spec/acceptance/active_model_spec.rb +115 -0
- data/spec/acceptance/broker_spec.rb +52 -0
- data/spec/acceptance/model_spec.rb +69 -0
- data/spec/acceptance/node_spec.rb +59 -0
- data/spec/acceptance/policy_spec.rb +82 -0
- data/spec/acceptance/tag_matcher_spec.rb +38 -0
- data/spec/acceptance/tag_spec.rb +43 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/unit/safety_razor/client_spec.rb +84 -0
- metadata +281 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'safety_razor/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "safety_razor"
|
8
|
+
spec.version = SafetyRazor::VERSION
|
9
|
+
spec.authors = ["Fletcher Nichol"]
|
10
|
+
spec.email = ["fnichol@nichol.ca"]
|
11
|
+
spec.description = %q{Safety Razor - A Ruby client for the Razor API.}
|
12
|
+
spec.summary = spec.description
|
13
|
+
spec.homepage = "https://github.com/blueboxgroup/safety_razor"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = []
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "hashie"
|
22
|
+
spec.add_dependency "faraday"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
|
27
|
+
spec.add_development_dependency "minitest"
|
28
|
+
spec.add_development_dependency 'mocha'
|
29
|
+
spec.add_development_dependency 'guard-minitest'
|
30
|
+
|
31
|
+
spec.add_development_dependency 'simplecov'
|
32
|
+
spec.add_development_dependency 'cane'
|
33
|
+
spec.add_development_dependency 'guard-cane'
|
34
|
+
spec.add_development_dependency 'tailor'
|
35
|
+
spec.add_development_dependency 'countloc'
|
36
|
+
end
|
data/script/bootstrap
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -e
|
3
|
+
[ -n "$BOOTSTRAP_DEBUG" ] && set -x
|
4
|
+
|
5
|
+
banner() { printf -- "-----> $*\n"; }
|
6
|
+
log() { printf -- " $*\n"; }
|
7
|
+
warn() { printf -- ">>>>>> $*\n"; }
|
8
|
+
fail() { printf -- "\nERROR: $*\n" ; exit 1 ; }
|
9
|
+
|
10
|
+
if ! command -v vagrant >/dev/null ; then
|
11
|
+
fail "An installation of Vagrant could not be found, please install a package"
|
12
|
+
fi
|
13
|
+
|
14
|
+
banner "Checking for Vagrant"
|
15
|
+
if [[ "$(vagrant --version)" < "Vagrant version 1.1.0" ]] ; then
|
16
|
+
fail "Only Vagrant versions 1.1.0 and up are supported, please update"
|
17
|
+
fi
|
18
|
+
|
19
|
+
banner "Checking for vagrant-omnibus Vagrant plugin"
|
20
|
+
if ! vagrant plugin list | grep -q '^vagrant-omnibus ' ; then
|
21
|
+
fail "Vagrant plugin vagrant-omnibus must be installed"
|
22
|
+
fi
|
23
|
+
|
24
|
+
banner "Checking for vagrant-berkshelf Vagrant plugin"
|
25
|
+
if ! vagrant plugin list | grep -q '^vagrant-berkshelf ' ; then
|
26
|
+
fail "Vagrant plugin vagrant-berkshelf must be installed"
|
27
|
+
fi
|
28
|
+
|
29
|
+
bundle_cmd="bundle install"
|
30
|
+
banner "Running '$bundle_cmd'"
|
31
|
+
$bundle_cmd
|
32
|
+
|
33
|
+
banner 'All ready!'
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha/setup'
|
5
|
+
|
6
|
+
require 'safety_razor'
|
7
|
+
|
8
|
+
describe "ActiveModel Slice" do
|
9
|
+
|
10
|
+
let(:client) { SafetyRazor::Client.new(:uri => 'http://127.0.0.1:8026') }
|
11
|
+
|
12
|
+
let(:images) do
|
13
|
+
%x{vagrant ssh --command 'sudo razor image get all'}.
|
14
|
+
split("\n\n").
|
15
|
+
collect{ |x| Hash[*(x.split(/\n|=>/) - ['Images']).
|
16
|
+
collect{|y| y.strip!}] }
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:node) do
|
20
|
+
client.node.register({
|
21
|
+
:hw_id => "000C29291C95",
|
22
|
+
:last_state => "idle",
|
23
|
+
:attributes_hash => {
|
24
|
+
:productname => "safety"
|
25
|
+
}
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:model) do
|
30
|
+
client.model.create({
|
31
|
+
:label => "test-model",
|
32
|
+
:image_uuid => image_uuid,
|
33
|
+
:template => "ubuntu_oneiric",
|
34
|
+
:req_metadata_hash => {
|
35
|
+
:hostname_prefix => "test",
|
36
|
+
:domainname => "testdomain.com",
|
37
|
+
:root_password => "test4321"
|
38
|
+
}
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
let(:tag) do
|
43
|
+
result = client.tag.create({
|
44
|
+
:name => "Safety",
|
45
|
+
:tag => "safety"
|
46
|
+
})
|
47
|
+
client.tag_matcher.create(result.uuid, {
|
48
|
+
:key => "productname",
|
49
|
+
:compare => "equal",
|
50
|
+
:value => "safety"
|
51
|
+
})
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:policy) do
|
56
|
+
client.policy.create({
|
57
|
+
:label => "Test Policy",
|
58
|
+
:model_uuid => model.uuid,
|
59
|
+
:template => "linux_deploy",
|
60
|
+
:tags => "safety",
|
61
|
+
:enabled => "true"
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
before do
|
66
|
+
script = [
|
67
|
+
%{d = ProjectRazor::Data.instance},
|
68
|
+
%{d.check_init},
|
69
|
+
%{d.delete_all_objects(:node)},
|
70
|
+
%{d.delete_all_objects(:active)},
|
71
|
+
%{e = ProjectRazor::Engine.instance}
|
72
|
+
].join(' ; ')
|
73
|
+
commands = [
|
74
|
+
%{sudo razor policy remove all},
|
75
|
+
%{sudo razor model remove all},
|
76
|
+
%{sudo razor tag remove all},
|
77
|
+
%{sudo ruby -I/opt/razor/lib -rproject_razor -e "#{script}"}
|
78
|
+
].join(' && ')
|
79
|
+
|
80
|
+
%x{vagrant ssh --command '#{commands}'}
|
81
|
+
|
82
|
+
tag # create tag and matcher
|
83
|
+
policy # create policy
|
84
|
+
node # create node
|
85
|
+
end
|
86
|
+
|
87
|
+
it "manages an active model" do
|
88
|
+
client.active_model.all.must_equal []
|
89
|
+
|
90
|
+
# check node in to match against a policy and create an active_model
|
91
|
+
client.node.checkin({
|
92
|
+
:hw_id => "000C29291C95",
|
93
|
+
:last_state => "idle"
|
94
|
+
})
|
95
|
+
|
96
|
+
all = client.active_model.all
|
97
|
+
all.size.must_equal 1
|
98
|
+
|
99
|
+
fetched_active_model = client.active_model.get(all.first.uuid)
|
100
|
+
fetched_active_model.node_uuid.must_equal node.uuid
|
101
|
+
|
102
|
+
client.active_model.destroy(fetched_active_model.uuid)
|
103
|
+
client.active_model.all.must_equal []
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def image_uuid(name = "ubuntu-minimal-10.04", version = "10.04")
|
109
|
+
result = images.find do |image|
|
110
|
+
image["OS Name"] == name && image["OS Version"] == version
|
111
|
+
end
|
112
|
+
|
113
|
+
result && result["UUID"]
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha/setup'
|
5
|
+
|
6
|
+
require 'safety_razor'
|
7
|
+
|
8
|
+
describe "Broker Slice" do
|
9
|
+
|
10
|
+
let(:client) { SafetyRazor::Client.new(:uri => 'http://127.0.0.1:8026') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
%x{vagrant ssh --command 'sudo razor broker remove all'}
|
14
|
+
end
|
15
|
+
|
16
|
+
it "manages a broker" do
|
17
|
+
client.broker.plugins.find { |t| t.plugin == "puppet" }.
|
18
|
+
description.must_equal "PuppetLabs PuppetMaster"
|
19
|
+
|
20
|
+
client.broker.all.must_equal []
|
21
|
+
|
22
|
+
broker = client.broker.create({
|
23
|
+
:name => "Chefy",
|
24
|
+
:plugin => "chef",
|
25
|
+
:description => "Production Chef Server",
|
26
|
+
:req_metadata_hash => {
|
27
|
+
:chef_server_url => "https://chef.example.com",
|
28
|
+
:chef_version => "11.4.0",
|
29
|
+
:validation_key => "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAK..."
|
30
|
+
}
|
31
|
+
})
|
32
|
+
broker.name.must_equal "Chefy"
|
33
|
+
broker.chef_version.must_equal "11.4.0"
|
34
|
+
|
35
|
+
all = client.broker.all
|
36
|
+
all.size.must_equal 1
|
37
|
+
all.first.uuid.must_equal broker.uuid
|
38
|
+
|
39
|
+
fetched_broker = client.broker.get(broker.uuid)
|
40
|
+
fetched_broker.uuid.must_equal broker.uuid
|
41
|
+
fetched_broker.name.must_equal "Chefy"
|
42
|
+
|
43
|
+
updated_broker = client.broker.update({
|
44
|
+
:uuid => broker.uuid,
|
45
|
+
:name => "Updated Chefy"
|
46
|
+
})
|
47
|
+
updated_broker.name.must_equal "Updated Chefy"
|
48
|
+
|
49
|
+
client.broker.destroy(broker.uuid)
|
50
|
+
client.broker.all.must_equal []
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha/setup'
|
5
|
+
|
6
|
+
require 'safety_razor'
|
7
|
+
|
8
|
+
describe "Model Slice" do
|
9
|
+
|
10
|
+
let(:client) { SafetyRazor::Client.new(:uri => 'http://127.0.0.1:8026') }
|
11
|
+
|
12
|
+
let(:images) do
|
13
|
+
%x{vagrant ssh --command 'sudo razor image get all'}.
|
14
|
+
split("\n\n").
|
15
|
+
collect{ |x| Hash[*(x.split(/\n|=>/) - ['Images']).
|
16
|
+
collect{|y| y.strip!}] }
|
17
|
+
end
|
18
|
+
|
19
|
+
before do
|
20
|
+
%x{vagrant ssh --command 'sudo razor model remove all'}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "manages a model" do
|
24
|
+
client.model.templates.
|
25
|
+
find { |t| t.name == "ubuntu_oneiric" }.template.must_equal "linux_deploy"
|
26
|
+
|
27
|
+
client.model.all.must_equal []
|
28
|
+
|
29
|
+
model = client.model.create({
|
30
|
+
:label => "test-model",
|
31
|
+
:image_uuid => image_uuid,
|
32
|
+
:template => "ubuntu_oneiric",
|
33
|
+
:req_metadata_hash => {
|
34
|
+
:hostname_prefix => "test",
|
35
|
+
:domainname => "testdomain.com",
|
36
|
+
:root_password => "test4321"
|
37
|
+
}
|
38
|
+
})
|
39
|
+
model.label.must_equal "test-model"
|
40
|
+
model.image_uuid.must_equal image_uuid
|
41
|
+
|
42
|
+
all = client.model.all
|
43
|
+
all.size.must_equal 1
|
44
|
+
all.first.uuid.must_equal model.uuid
|
45
|
+
|
46
|
+
fetched_model = client.model.get(model.uuid)
|
47
|
+
fetched_model.uuid.must_equal model.uuid
|
48
|
+
fetched_model.label.must_equal "test-model"
|
49
|
+
|
50
|
+
updated_model = client.model.update({
|
51
|
+
:uuid => model.uuid,
|
52
|
+
:label => "updated-test-model"
|
53
|
+
})
|
54
|
+
updated_model.label.must_equal "updated-test-model"
|
55
|
+
|
56
|
+
client.model.destroy(model.uuid)
|
57
|
+
client.model.all.must_equal []
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def image_uuid(name = "ubuntu-minimal-10.04", version = "10.04")
|
63
|
+
result = images.find do |image|
|
64
|
+
image["OS Name"] == name && image["OS Version"] == version
|
65
|
+
end
|
66
|
+
|
67
|
+
result && result["UUID"]
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha/setup'
|
5
|
+
|
6
|
+
require 'safety_razor'
|
7
|
+
|
8
|
+
describe "Node Slice" do
|
9
|
+
|
10
|
+
let(:client) { SafetyRazor::Client.new(:uri => 'http://127.0.0.1:8026') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
# sadly there isn't a way to delete nodes via any API so we can get evil
|
14
|
+
# and creative instead
|
15
|
+
script = [
|
16
|
+
%{i = ProjectRazor::Data.instance},
|
17
|
+
%{i.check_init},
|
18
|
+
%{i.delete_all_objects(:node)}
|
19
|
+
].join(' ; ')
|
20
|
+
command = %{sudo ruby -I/opt/razor/lib -rproject_razor -e "#{script}"}
|
21
|
+
|
22
|
+
%x{vagrant ssh --command '#{command}'}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "manages a node" do
|
26
|
+
client.node.all.must_equal []
|
27
|
+
|
28
|
+
node = client.node.register({
|
29
|
+
:hw_id => "000C29291C95",
|
30
|
+
:last_state => "idle",
|
31
|
+
:attributes_hash => {
|
32
|
+
:attr1 => "val1",
|
33
|
+
:attr2 => "val2"
|
34
|
+
}
|
35
|
+
})
|
36
|
+
node.hw_id.first.must_equal "000C29291C95"
|
37
|
+
node.last_state.must_equal "idle"
|
38
|
+
|
39
|
+
all = client.node.all
|
40
|
+
all.size.must_equal 1
|
41
|
+
all.first.hw_id.must_equal node.hw_id
|
42
|
+
|
43
|
+
fetched_node = client.node.get(node.uuid)
|
44
|
+
fetched_node.uuid.must_equal node.uuid
|
45
|
+
fetched_node.last_state.must_equal "idle"
|
46
|
+
|
47
|
+
client.node.checkin({
|
48
|
+
:hw_id => "000C29291C95",
|
49
|
+
:last_state => "baked"
|
50
|
+
})
|
51
|
+
client.node.get(node.uuid).last_state.must_equal "baked"
|
52
|
+
|
53
|
+
attrs = client.node.get_attributes(node.uuid)
|
54
|
+
attrs['attr1'].must_equal "val1"
|
55
|
+
attrs['attr2'].must_equal "val2"
|
56
|
+
|
57
|
+
client.node.get_hardware_ids(node.uuid).must_equal node.hw_id
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha/setup'
|
5
|
+
|
6
|
+
require 'safety_razor'
|
7
|
+
|
8
|
+
describe "Policy Slice" do
|
9
|
+
|
10
|
+
let(:client) { SafetyRazor::Client.new(:uri => 'http://127.0.0.1:8026') }
|
11
|
+
|
12
|
+
let(:images) do
|
13
|
+
%x{vagrant ssh --command 'sudo razor image get all'}.
|
14
|
+
split("\n\n").
|
15
|
+
collect{ |x| Hash[*(x.split(/\n|=>/) - ['Images']).
|
16
|
+
collect{|y| y.strip!}] }
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:model) do
|
20
|
+
client.model.create({
|
21
|
+
:label => "test-model",
|
22
|
+
:image_uuid => image_uuid,
|
23
|
+
:template => "ubuntu_oneiric",
|
24
|
+
:req_metadata_hash => {
|
25
|
+
:hostname_prefix => "test",
|
26
|
+
:domainname => "testdomain.com",
|
27
|
+
:root_password => "test4321"
|
28
|
+
}
|
29
|
+
})
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
commands = [
|
34
|
+
"sudo razor policy remove all",
|
35
|
+
"sudo razor model remove all",
|
36
|
+
].join(' && ')
|
37
|
+
%x{vagrant ssh --command '#{commands}'}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "manages a policy" do
|
41
|
+
client.policy.templates.
|
42
|
+
find { |t| t.template == "linux_deploy" }.is_template.must_equal true
|
43
|
+
|
44
|
+
client.policy.all.must_equal []
|
45
|
+
|
46
|
+
policy = client.policy.create({
|
47
|
+
label: "Test Policy",
|
48
|
+
model_uuid: model.uuid,
|
49
|
+
template: "linux_deploy",
|
50
|
+
tags: "two_disks,memsize_1GiB,nics_2"
|
51
|
+
})
|
52
|
+
policy.label.must_equal "Test Policy"
|
53
|
+
policy.model.uuid.must_equal model.uuid
|
54
|
+
|
55
|
+
all = client.policy.all
|
56
|
+
all.size.must_equal 1
|
57
|
+
all.first.uuid.must_equal policy.uuid
|
58
|
+
|
59
|
+
fetched_policy = client.policy.get(policy.uuid)
|
60
|
+
fetched_policy.uuid.must_equal policy.uuid
|
61
|
+
fetched_policy.label.must_equal "Test Policy"
|
62
|
+
|
63
|
+
updated_policy = client.policy.update({
|
64
|
+
:uuid => policy.uuid,
|
65
|
+
:tags => "one,two,three"
|
66
|
+
})
|
67
|
+
updated_policy.tags.must_equal %w{one two three}
|
68
|
+
|
69
|
+
client.policy.destroy(policy.uuid)
|
70
|
+
client.policy.all.must_equal []
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def image_uuid(name = "ubuntu-minimal-10.04", version = "10.04")
|
76
|
+
result = images.find do |image|
|
77
|
+
image["OS Name"] == name && image["OS Version"] == version
|
78
|
+
end
|
79
|
+
|
80
|
+
result && result["UUID"]
|
81
|
+
end
|
82
|
+
end
|