weavr 0.0.5 → 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/README.md CHANGED
@@ -98,4 +98,32 @@ Adjust the repositories used to install components:
98
98
 
99
99
  ```ruby
100
100
  Weavr.configure_repository(version: '2.1', os: 'redhat6', repo: 'HDP-2.1', url: 'http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.1.3.0/')
101
- ```
101
+ ```
102
+
103
+ ### Blueprints
104
+
105
+ As of 1.6.0, Ambari supports blueprints, which are a convenient way to save
106
+ and reuse ambari hadoop cluster configurations.
107
+
108
+ For more info on blueprints, see [this blog post](http://hortonworks.com/blog/ambari-blueprints-delivers-missing-component-cluster-provisioning/) or [the ambari wiki](https://cwiki.apache.org/confluence/display/AMBARI/Blueprints).
109
+
110
+ Sample usage:
111
+
112
+ ```ruby
113
+ service_blueprint_name = 'blueprint-hwx'
114
+ cluster_name = 'hwx'
115
+ service_blueprint_filename = 'hdp_blueprint_services.json'
116
+ cluster_blueprint_filename = 'hdp_blueprint_cluster.json'
117
+ create_request = Weavr.create_cluster_from_blueprint(
118
+ service_blueprint_name,
119
+ cluster_name,
120
+ service_blueprint_filename,
121
+ cluster_blueprint_filename
122
+ )
123
+
124
+ # wait for services to install and start
125
+ while create_request.id && create_request.progress_percent != 100.0
126
+ sleep 5
127
+ create_request.refresh!
128
+ end
129
+ ```
@@ -4,6 +4,7 @@ require 'faraday_middleware'
4
4
  require 'gorillib/builder'
5
5
  require 'gorillib/model/type/extended'
6
6
  require 'logger'
7
+ require 'multi_json'
7
8
 
8
9
  require 'weavr/connection'
9
10
  require 'weavr/error'
@@ -71,6 +72,25 @@ module Weavr
71
72
  cluster.create options
72
73
  end
73
74
 
75
+ def create_cluster_from_blueprint(blueprint_name, cluster_name, services_blueprint_filename, cluster_blueprint_filename)
76
+ blueprint = Blueprint.receive(blueprint_name: blueprint_name, href: File.join('blueprints', blueprint_name))
77
+ blueprint.create services_blueprint_filename
78
+ cluster = Cluster.receive(cluster_name: cluster_name, href: File.join('clusters', cluster_name))
79
+ cluster.create_from_blueprint cluster_blueprint_filename
80
+ end
81
+
82
+ def create_cluster_from_json(blueprint_name, cluster_name, filename)
83
+ blueprint = Blueprint.receive(blueprint_name: blueprint_name, href: File.join('blueprints', blueprint_name))
84
+ begin
85
+ data = MultiJson.load File.open(filename, 'r')
86
+ rescue Exception => e
87
+ raise e.message, Weavr::BlueprintError
88
+ end
89
+ blueprint.create_from_data data['services']
90
+ cluster = Cluster.receive(cluster_name: cluster_name, href: File.join('clusters', cluster_name))
91
+ cluster.create_from_blueprint_data data['cluster']
92
+ end
93
+
74
94
  def stacks
75
95
  Collection.of(Stack).receive connection.resource(:get, 'stacks2')
76
96
  end
@@ -2,4 +2,5 @@ module Weavr
2
2
  Error = Class.new Exception
3
3
  ConnectionError = Class.new Error
4
4
  RequestError = Class.new Error
5
+ BlueprintError = Class.new Error
5
6
  end
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Weavr
3
+ class Blueprint < Resource
4
+ field :blueprint_name, String
5
+
6
+ # GET /blueprints
7
+ # Returns the available blueprints.
8
+ def get_blueprints
9
+ connection.resource(:get, 'blueprints')
10
+ end
11
+
12
+ # POST /blueprints/:name
13
+ # Creates a blueprint.

14
+ # example:
15
+ # curl -H "X-Requested-By: ambari" -d @hdp_sample_blueprint.txt -u admin:admin \
16
+ # -XPOST http://localhost:8080/api/v1/blueprints/blueprint-hwx
17
+ def create services_blueprint_filename
18
+ begin
19
+ data = MultiJson.load File.open(services_blueprint_filename, 'r')
20
+ rescue Exception => e
21
+ raise e.message, Weavr::BlueprintError
22
+ end
23
+ create_from_data data
24
+ end
25
+
26
+ def create_from_data data
27
+ resource_action(:post, data)
28
+ self
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # Declare all classes ahead of time to avoid dependency problems
2
- %w[ Cluster Collection Component Configuration Host
2
+ %w[ Blueprint Cluster Collection Component Configuration Host
3
3
  HostRole OperatingSystem Repository Request
4
4
  Service ServiceComponent Stack StackConfiguration
5
5
  StackService StackVersion Task
@@ -52,6 +52,33 @@ module Weavr
52
52
  refresh!
53
53
  end
54
54
 
55
+ # POST /clusters/:name
56
+ # Creates a cluster.
57
+ # Since this installs and starts services, return result of Request.receive(res)
58
+ # example
59
+ # curl -H "X-Requested-By: ambari" -d @hdp_blueprint_cluster.json -u admin:admin \
60
+ # -XPOST http://localhost:8080/api/v1/clusters/blueprint-hwx
61
+ def create_from_blueprint cluster_blueprint_filename
62
+ begin
63
+ data = MultiJson.load File.open(cluster_blueprint_filename, 'r')
64
+ rescue Exception => e
65
+ raise e.message, Weavr::BlueprintError
66
+ end
67
+ create_from_blueprint_data data
68
+ end
69
+
70
+ def create_from_blueprint_data data
71
+ res = resource_action(:post, data)
72
+ Request.receive(res || { })
73
+ end
74
+
75
+ # GET /clusters/:name?format=blueprint
76
+ # Export the current cluster layout as a blueprint.
77
+ # TODO: add GET param handling to Weavr::Connection#resource
78
+ def get_blueprint name
79
+ connection.resource(:get, "clusters/#{name}?format=blueprint")
80
+ end
81
+
55
82
  def delete
56
83
  resource_action(:delete)
57
84
  end
@@ -15,6 +15,7 @@ module Weavr
15
15
  field :request_status, String
16
16
  field :resource_filter, Array
17
17
  field :start_time, Integer # Needs to be Date
18
+ field :status, String
18
19
  field :task_count, Integer
19
20
  field :timed_out_task_count, Integer
20
21
  field :type, String
@@ -18,7 +18,7 @@ module Weavr
18
18
  end
19
19
 
20
20
  def install
21
- to_state'INSTALLED'
21
+ to_state 'INSTALLED'
22
22
  end
23
23
 
24
24
  def stop
@@ -1,3 +1,3 @@
1
1
  module Weavr
2
- VERSION = '0.0.5'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -10,7 +10,12 @@ describe Weavr do
10
10
 
11
11
  subject(:weavr) { described_class }
12
12
  subject(:collection_resource){ Weavr::Collection }
13
+ subject(:blueprint_resource) { Weavr::Blueprint }
13
14
  subject(:cluster_resource) { Weavr::Cluster }
15
+ subject(:request_resource) { Weavr::Request }
16
+
17
+ # dummy json data for mock blueprints
18
+ let(:data) {"{}"}
14
19
 
15
20
  after(:each) do
16
21
  clear_variables described_class
@@ -78,6 +83,39 @@ describe Weavr do
78
83
  end
79
84
  end
80
85
 
86
+ context '.get_blueprints' do
87
+ it 'gets all available blueprints' do
88
+ weavr.connection.should_receive(:resource).with(:get, 'blueprints')
89
+ blueprint = blueprint_resource.new(href: 'blueprints')
90
+ blueprint.get_blueprints
91
+ end
92
+
93
+ it 'generates a blueprint from a cluster' do
94
+ weavr.connection.should_receive(:resource).with(:get, 'clusters/foo?format=blueprint')
95
+ cluster = cluster_resource.new
96
+ cluster.get_blueprint 'foo'
97
+ end
98
+ end
99
+
100
+ context '.create_cluster_from_blueprint' do
101
+ it 'creates a new blueprint' do
102
+ File.stub(:open).with('baz.json','r') { StringIO.new(data) }
103
+ weavr.connection.should_receive(:resource).with(:post, 'blueprints/foo', an_instance_of(Hash))
104
+ blueprint = blueprint_resource.new(blueprint_name: 'foo', href: 'blueprints/foo')
105
+ blueprint.create 'baz.json'
106
+ end
107
+
108
+ it 'creates a new cluster from a blueprint' do
109
+ File.stub(:open).with('baz.json','r') { StringIO.new(data) }
110
+ weavr.connection.should_receive(:resource).with(:post, 'clusters/foo', an_instance_of(Hash))
111
+ cluster = cluster_resource.new(cluster_name: 'foo', href: 'clusters/foo')
112
+ req = cluster.create_from_blueprint 'baz.json'
113
+ expect(cluster).to be_a(cluster_resource)
114
+ expect(cluster.cluster_name).to eq('foo')
115
+ expect(req).to be_a(request_resource)
116
+ end
117
+ end
118
+
81
119
  context '.stacks' do
82
120
  it 'returns a collection of stacks' do
83
121
  weavr.connection.should_receive(:resource).with(:get, 'stacks2').and_return(items: [{ stack_name: 'hdp' }])
@@ -25,4 +25,5 @@ Gem::Specification.new do |gem|
25
25
  gem.add_dependency('faraday', '~> 0.9.0')
26
26
  gem.add_dependency('faraday_middleware', '~> 0.9.1')
27
27
  gem.add_dependency('gorillib-model', '~> 0.0.1')
28
+ gem.add_dependency('multi_json', '~> 1.10.1')
28
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weavr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-08-11 00:00:00.000000000 Z
12
+ date: 2014-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
93
  version: 0.0.1
94
+ - !ruby/object:Gem::Dependency
95
+ name: multi_json
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.10.1
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.10.1
94
110
  description: Weavr
95
111
  email:
96
112
  - dempsey.travis@gmail.com
@@ -107,6 +123,7 @@ files:
107
123
  - lib/weavr/connection.rb
108
124
  - lib/weavr/error.rb
109
125
  - lib/weavr/resource.rb
126
+ - lib/weavr/resource/blueprint.rb
110
127
  - lib/weavr/resource/class_map.rb
111
128
  - lib/weavr/resource/cluster.rb
112
129
  - lib/weavr/resource/collection.rb
@@ -144,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
161
  version: '0'
145
162
  segments:
146
163
  - 0
147
- hash: 1159751241335575004
164
+ hash: -3914216349381186348
148
165
  required_rubygems_version: !ruby/object:Gem::Requirement
149
166
  none: false
150
167
  requirements:
@@ -153,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
170
  version: '0'
154
171
  segments:
155
172
  - 0
156
- hash: 1159751241335575004
173
+ hash: -3914216349381186348
157
174
  requirements: []
158
175
  rubyforge_project:
159
176
  rubygems_version: 1.8.23