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/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