safety_razor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Vagrantfile ADDED
@@ -0,0 +1,27 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ config.vm.box = "opscode-ubuntu-12.04"
6
+ config.vm.box_url = "https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box"
7
+
8
+ config.vm.network :forwarded_port, guest: 8026, host: 8026
9
+
10
+ config.omnibus.chef_version = :latest
11
+ config.berkshelf.enabled = true
12
+
13
+ config.vm.provision :chef_solo do |chef|
14
+ chef.run_list = ["recipe[razor]"]
15
+ chef.json = {
16
+ :razor => {
17
+ :images => {
18
+ 'ubuntu-minimal-10.04' => {
19
+ 'url' => 'http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/current/images/netboot/mini.iso',
20
+ 'checksum' => '72602f91a85a856248e519c6446d303fa8990b4328899385990a95177681dc58',
21
+ 'version' => '10.04'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "safety_razor/version"
4
+ require "safety_razor/client"
5
+
6
+ module SafetyRazor
7
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'faraday'
4
+
5
+ require 'safety_razor/slice/active_model'
6
+ require 'safety_razor/slice/broker'
7
+ require 'safety_razor/slice/model'
8
+ require 'safety_razor/slice/node'
9
+ require 'safety_razor/slice/policy'
10
+ require 'safety_razor/slice/tag'
11
+ require 'safety_razor/slice/tag_matcher'
12
+
13
+ module SafetyRazor
14
+
15
+ # Client object which manages the connection to the Razor API endpoint.
16
+ #
17
+ # @author Fletcher Nichol <fnichol@nichol.ca>
18
+ #
19
+ class Client
20
+
21
+ attr_reader :connection
22
+
23
+ def initialize(options = {})
24
+ @connection = Faraday.new(:url => options[:uri]) do |faraday|
25
+ faraday.request :url_encoded
26
+ faraday.adapter Faraday.default_adapter
27
+ end
28
+ end
29
+
30
+ def active_model
31
+ @active_model ||= Slice::ActiveModel.new(self)
32
+ end
33
+
34
+ def broker
35
+ @broker ||= Slice::Broker.new(self)
36
+ end
37
+
38
+ def model
39
+ @model ||= Slice::Model.new(self)
40
+ end
41
+
42
+ def node
43
+ @node ||= Slice::Node.new(self)
44
+ end
45
+
46
+ def policy
47
+ @policy ||= Slice::Policy.new(self)
48
+ end
49
+
50
+ def tag
51
+ @tag ||= Slice::Tag.new(self)
52
+ end
53
+
54
+ def tag_matcher
55
+ @tag_matcher ||= Slice::TagMatcher.new(self)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's active model slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class ActiveModel < Base
14
+
15
+ def create(params)
16
+ raise NoMethodError, "Node#create is not defined"
17
+ end
18
+
19
+ def update(params)
20
+ raise NoMethodError, "Node#update is not defined"
21
+ end
22
+
23
+ private
24
+
25
+ def slice_name
26
+ "active_model"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,89 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'json'
4
+ require 'hashie'
5
+
6
+ module SafetyRazor
7
+
8
+ module Slice
9
+
10
+ # Common behavior for Razor's model slices.
11
+ #
12
+ # @author Fletcher Nichol <fnichol@nichol.ca>
13
+ #
14
+ class Base
15
+
16
+ def initialize(client)
17
+ @client = client
18
+ end
19
+
20
+ def create(params)
21
+ payload = JSON.generate(params)
22
+ response = connection.post(slice_path, 'json_hash' => payload)
23
+ parse(response).first
24
+ end
25
+
26
+ def get(uuid)
27
+ response = connection.get(slice_path(uuid))
28
+ parse(response).first
29
+ end
30
+
31
+ def all
32
+ response = connection.get(slice_path)
33
+ parse(response)
34
+ end
35
+
36
+ def update(params)
37
+ payload = JSON.generate(params)
38
+ uuid = params[:uuid]
39
+ response = connection.put(slice_path(uuid), 'json_hash' => payload)
40
+ parse(response).first
41
+ end
42
+
43
+ def destroy(uuid)
44
+ connection.delete(slice_path(uuid))
45
+ end
46
+
47
+ protected
48
+
49
+ attr_reader :client
50
+
51
+ def connection
52
+ client.connection
53
+ end
54
+
55
+ def slice_path(uuid = nil)
56
+ path = "/razor/api/#{slice_name}"
57
+ path += "/#{uuid}" if uuid
58
+ path
59
+ end
60
+
61
+ def parse(response)
62
+ collection = JSON.parse(response.body)["response"]
63
+ collection = [collection] if collection.is_a?(Hash)
64
+
65
+ Array(collection).map { |obj| new_mash(strip_ivars(obj)) }
66
+ end
67
+
68
+ def new_mash(obj)
69
+ Hashie::Mash.new(obj)
70
+ end
71
+
72
+ def strip_ivars(obj)
73
+ case obj
74
+ when Hash
75
+ stripped = Hash.new
76
+ obj.each_pair do |key, value|
77
+ new_key = key.is_a?(String) ? key.sub(/^@/, '') : key
78
+ stripped[new_key] = strip_ivars(value)
79
+ end
80
+ stripped
81
+ when Array
82
+ obj.map { |value| strip_ivars(value) }
83
+ else
84
+ obj
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's broker slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class Broker < Base
14
+
15
+ def plugins
16
+ response = connection.get(slice_path("plugins"))
17
+ parse(response)
18
+ end
19
+
20
+ private
21
+
22
+ def slice_name
23
+ "broker"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's model slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class Model < Base
14
+
15
+ def templates
16
+ response = connection.get(slice_path("templates"))
17
+ parse(response)
18
+ end
19
+
20
+ private
21
+
22
+ def slice_name
23
+ "model"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's node slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class Node < Base
14
+
15
+ def register(params)
16
+ payload = JSON.generate(params)
17
+ response = connection.post(slice_path("register"),
18
+ 'json_hash' => payload)
19
+ parse(response).first
20
+ end
21
+
22
+ def checkin(params)
23
+ payload = JSON.generate(params)
24
+ response = connection.post(slice_path("checkin"),
25
+ 'json_hash' => payload)
26
+ parse(response).first
27
+ end
28
+
29
+ def get_attributes(uuid)
30
+ response = connection.get(slice_path(uuid), "field" => "attributes")
31
+ parse(response).first
32
+ end
33
+
34
+ def get_hardware_ids(uuid)
35
+ response = connection.get(slice_path(uuid), "field" => "hardware_ids")
36
+ parse(response).first["hw_id"]
37
+ end
38
+
39
+ def create(params)
40
+ raise NoMethodError, "Node#create is not defined"
41
+ end
42
+
43
+ def update(params)
44
+ raise NoMethodError, "Node#update is not defined"
45
+ end
46
+
47
+ def destroy(uuid)
48
+ raise NoMethodError, "Node#destroy is not defined"
49
+ end
50
+
51
+ private
52
+
53
+ def slice_name
54
+ "node"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's policy slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class Policy < Base
14
+
15
+ def templates
16
+ response = connection.get(slice_path("templates"))
17
+ parse(response)
18
+ end
19
+
20
+ private
21
+
22
+ def slice_name
23
+ "policy"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's tag slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class Tag < Base
14
+
15
+ private
16
+
17
+ def slice_name
18
+ "tag"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'safety_razor/slice/base'
4
+
5
+ module SafetyRazor
6
+
7
+ module Slice
8
+
9
+ # Client API for Razor's tag matcher slice.
10
+ #
11
+ # @author Fletcher Nichol <fnichol@nichol.ca>
12
+ #
13
+ class TagMatcher < Base
14
+
15
+ def create(tag_uuid, params)
16
+ payload = JSON.generate(params)
17
+ response = connection.post(slice_path(tag_uuid), 'json_hash' => payload)
18
+ parse(response).first
19
+ end
20
+
21
+ def get(tag_uuid, uuid)
22
+ response = connection.get(slice_path(tag_uuid, uuid))
23
+ parse(response).first
24
+ end
25
+
26
+ def all
27
+ raise NoMethodError, "TagMatcher#all is not defined"
28
+ end
29
+
30
+ def update(tag_uuid, params)
31
+ payload = JSON.generate(params)
32
+ uuid = params[:uuid]
33
+ response = connection.put(slice_path(tag_uuid, uuid),
34
+ 'json_hash' => payload)
35
+ parse(response).first
36
+ end
37
+
38
+ def destroy(tag_uuid, uuid)
39
+ connection.delete(slice_path(tag_uuid, uuid))
40
+ end
41
+
42
+ protected
43
+
44
+ def slice_path(tag_uuid, uuid = nil)
45
+ path = "/razor/api/tag/#{tag_uuid}/matcher"
46
+ path += "/#{uuid}" if uuid
47
+ path
48
+ end
49
+
50
+ def new_mash(obj)
51
+ Hashie::Mash.new(obj).extend(KeyReaderMethod)
52
+ end
53
+
54
+ # Overrides a Hash method collision with the tag matcher attribute of
55
+ # `key'.
56
+ #
57
+ module KeyReaderMethod
58
+
59
+ def key
60
+ self["key"]
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end