deis-client 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/Rakefile +8 -0
- data/deis_client.gemspec +14 -0
- data/lib/deis_client.rb +174 -0
- data/test/test_deis_client.rb +112 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 58e6e3b57178229a12238962facc11faa3e81cb1
|
4
|
+
data.tar.gz: 69ca12a1ffda0e319ca5d2229cb2349ef401253f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a015c5ac514dceb06d4460be73c1cb09fdbc4674de061b9c2fb8c392d04a167aca37c7ce165e07ef30fb076080d14972c46ace05f815e4f0fe00842b6d18779a
|
7
|
+
data.tar.gz: 701a4f5f4848ed78552048b7c952d8d120a817e81aacd0db5a68d27390521f87e719122684bc31f540f163fe7d9b563a421cb40338b726c98b3d2d47cfb29074
|
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/vendor/bundle
|
26
|
+
/lib/bundler/man/
|
27
|
+
|
28
|
+
# for a library or gem, you might want to ignore these files since the code is
|
29
|
+
# intended to run in multiple environments; otherwise, check them in:
|
30
|
+
# Gemfile.lock
|
31
|
+
# .ruby-version
|
32
|
+
# .ruby-gemset
|
33
|
+
|
34
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
35
|
+
.rvmrc
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 AnyPresence, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# deis-client
|
data/Rakefile
ADDED
data/deis_client.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'deis-client'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = '2015-07-08'
|
5
|
+
s.summary = "Deis REST operations in a Ruby gem."
|
6
|
+
s.description = "Deis Platform REST (V1.5) client for Ruby."
|
7
|
+
s.authors = ["AnyPresence"]
|
8
|
+
s.email = 'engineering@anypresence.com'
|
9
|
+
s.files = `git ls-files -z`.split("\0")
|
10
|
+
s.homepage = 'http://rubygems.org/gems/deis_client'
|
11
|
+
s.license = 'MIT'
|
12
|
+
s.add_dependency('rest-client', '>= 1.6.7', '< 2.0')
|
13
|
+
s.required_ruby_version = '>= 1.9.3'
|
14
|
+
end
|
data/lib/deis_client.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'rest-client'
|
3
|
+
|
4
|
+
class DeisError < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class DeisClient
|
8
|
+
attr_reader :user_token
|
9
|
+
|
10
|
+
REQUEST_TIMEOUT = 180 #seconds
|
11
|
+
VERIFY_SSL = false
|
12
|
+
|
13
|
+
def initialize(controller_uri, username, password, mock=false)
|
14
|
+
@mock = mock
|
15
|
+
raise DeisError.new("No username or password detected!") if username.nil? || password.nil?
|
16
|
+
raise DeisError.new("You must specify a URI for Deis controller!") unless controller_uri =~ /\A#{URI::regexp}\z/
|
17
|
+
@deis_controller = controller_uri
|
18
|
+
login(username, password)
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def login(username, password)
|
23
|
+
if @mock
|
24
|
+
@user_token = "ABC123"
|
25
|
+
else
|
26
|
+
payload = {"username" => username, "password" => password}
|
27
|
+
response = RestClient::Request.execute(:method => :post, :url => login_url, :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => {:content_type => :json, :accept => :json})
|
28
|
+
body = JSON.parse response.body
|
29
|
+
@user_token = body.fetch('token')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def app_create(app_name)
|
34
|
+
if @mock
|
35
|
+
{}
|
36
|
+
else
|
37
|
+
payload = app_name.nil? ? Hash.new : {"id" => app_name}
|
38
|
+
response = RestClient::Request.execute(:method => :post, :url => apps_url, :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
39
|
+
JSON.parse response.body
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def app_destroy(app_name)
|
44
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
45
|
+
if @mock
|
46
|
+
{}
|
47
|
+
else
|
48
|
+
response = RestClient::Request.execute(:method => :delete, :url => app_url(app_name), :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
49
|
+
response.code == 204
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def app_scale(app_name, process_type, process_count)
|
54
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
55
|
+
raise DeisError.new("Process type is required. Supported values are 'web' or 'worker'") unless ["web", "worker"].include? process_type
|
56
|
+
raise DeisError.new("Process count is required") unless process_count.is_a? Fixnum
|
57
|
+
raise DeisError.new("Process count cannnot be negative") if process_count < 0
|
58
|
+
if @mock
|
59
|
+
false
|
60
|
+
else
|
61
|
+
payload = {process_type => process_count}
|
62
|
+
response = RestClient::Request.execute(:method => :post, :url => scale_url(app_name), :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
63
|
+
response.code == 204
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def app_restart(app_name)
|
68
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
69
|
+
if @mock
|
70
|
+
false
|
71
|
+
else
|
72
|
+
response = RestClient::Request.execute(:method => :post, :url => app_restart_url(app_name), :payload => {}.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
73
|
+
response.code == 200
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def key_add(user_name, ssh_public_key)
|
79
|
+
raise DeisError.new("Username is required") if user_name.nil?
|
80
|
+
raise DeisError.new("SSH key is required") if ssh_public_key.nil?
|
81
|
+
if @mock
|
82
|
+
{}
|
83
|
+
else
|
84
|
+
payload = {"id" => user_name, "public" => ssh_public_key}
|
85
|
+
response = RestClient::Request.execute(:method => :post, :url => keys_url, :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
86
|
+
JSON.parse response.body
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def config_set(app_name, config_hash={})
|
91
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
92
|
+
if @mock || config_hash.empty?
|
93
|
+
{}
|
94
|
+
else
|
95
|
+
payload = {"values" => config_hash}
|
96
|
+
response = RestClient::Request.execute(:method => :post, :url => config_url(app_name), :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
97
|
+
JSON.parse response.body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def config_get(app_name)
|
102
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
103
|
+
if @mock
|
104
|
+
{}
|
105
|
+
else
|
106
|
+
response = RestClient::Request.execute(:method => :get, :url => config_url(app_name), :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
107
|
+
hash = JSON.parse response.body
|
108
|
+
hash["values"]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def logs_get(app_name)
|
113
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
114
|
+
if @mock
|
115
|
+
{}
|
116
|
+
else
|
117
|
+
RestClient::Request.execute(:method => :get, :url => log_url(app_name), :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def command_run(app_name, command)
|
122
|
+
raise DeisError.new("App name is required") if app_name.nil?
|
123
|
+
raise DeisError.new("Command string is required") if command.nil?
|
124
|
+
if @mock
|
125
|
+
{}
|
126
|
+
else
|
127
|
+
payload = {"command" => command}
|
128
|
+
response = RestClient::Request.execute(:method => :post, :url => command_run_url(app_name), :payload => payload.to_json, :timeout => REQUEST_TIMEOUT, :verify_ssl => VERIFY_SSL, :headers => headers)
|
129
|
+
JSON.parse response.body
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def login_url
|
136
|
+
"#{@deis_controller}/v1/auth/login/"
|
137
|
+
end
|
138
|
+
|
139
|
+
def apps_url
|
140
|
+
"#{@deis_controller}/v1/apps/"
|
141
|
+
end
|
142
|
+
|
143
|
+
def app_url(app_name)
|
144
|
+
"#{apps_url}#{app_name}/"
|
145
|
+
end
|
146
|
+
|
147
|
+
def app_restart_url(app_name)
|
148
|
+
"#{app_url(app_name)}containers/restart/"
|
149
|
+
end
|
150
|
+
|
151
|
+
def config_url(app_name)
|
152
|
+
"#{app_url(app_name)}config/"
|
153
|
+
end
|
154
|
+
|
155
|
+
def scale_url(app_name)
|
156
|
+
"#{app_url(app_name)}scale/"
|
157
|
+
end
|
158
|
+
|
159
|
+
def log_url(app_name)
|
160
|
+
"#{app_url(app_name)}logs/"
|
161
|
+
end
|
162
|
+
|
163
|
+
def command_run_url(app_name)
|
164
|
+
"#{app_url(app_name)}run/"
|
165
|
+
end
|
166
|
+
|
167
|
+
def keys_url
|
168
|
+
"#{@deis_controller}/v1/keys/"
|
169
|
+
end
|
170
|
+
|
171
|
+
def headers
|
172
|
+
{:Authorization => "token #{@user_token}", :content_type => :json, :accept => :json}
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'deis_client'
|
3
|
+
|
4
|
+
class DeisClientTest < Minitest::Test
|
5
|
+
def self.test_order
|
6
|
+
:alpha
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@username = ENV['DEIS_ADMIN_USER'] || 'humpty'
|
11
|
+
@password = ENV['DEIS_ADMIN_PASSWORD'] || 'dumpty'
|
12
|
+
@mock = true
|
13
|
+
@instance_name = 'luxury-jumpsuit'
|
14
|
+
@client = DeisClient.new(ENV['DEIS_CONTROLLER'] || "http://controller.example.com",
|
15
|
+
@username,
|
16
|
+
@password,
|
17
|
+
@mock
|
18
|
+
)
|
19
|
+
@key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDZ47ISBG2bIQYV62g5qC58tRvHKh+OMITuxT/YyZzIZYmpDncmDLvaBVX7e3/V5d4CdJui/0pHGW/lnUtUUnTwexO1RABPENiCmUQAD7+QZbKyrYE43GHcXcZjEnAJIDt0FmRjGPFr99x/1kuKCAsouly6uTeRgt3DIjJWCkfvo5PBsdezgChcMCj3EDBqlR83qNFnL+at2I73Fv7GdNV/n7ORSru9POUGAqjdAv2jw02eZYKrxCZPRGimYRe+o0G7aMc6GDjWmonSL08yLryKIjrBD7C+YAzO8Z9UTF2EjgHQ2pKGQuPB5YS8X5APGQAy7HVWlMgBK6jcDuKz9ITLcKkkLUpX4ILch3ppR9OahxYCyJsTegHE3Vwtd0lP53eP/XsPOtMmd+gMch+N/HcK8N9U3c/3+LQpof1KG/SzFvOcplj7G29FDuMI9ziFkOxj7HBjJb4q3LYvOHAfFJIdmLcEH5ckyodxVRCKkravMJRT9X9S8G2MkX+J9/qH/3HNedgvWuqvtCdaozWnjTTU2yoLKUdoMKt1FHRLNLJKFdi27+sapTfP0Cs4IR8LY9sZw1LRk7YzCz21nb5jQs6X/npt2Szv7z0WZ/QUl81jQN6iVY4A5XZDy5cx9mXkxuBYSMl1PMLOR2k30bk6hnTmurhHFAgcDdmOQ3qhq9eUmQ== user@example.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def test_app_create
|
24
|
+
response = @client.app_create(nil)
|
25
|
+
unless @mock
|
26
|
+
app = response["id"]
|
27
|
+
assert response["id"]
|
28
|
+
assert response["owner"] == @username
|
29
|
+
assert response["uuid"]
|
30
|
+
response = @client.logs_get(app)
|
31
|
+
assert response.size > 0
|
32
|
+
response = @client.app_destroy(app)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
=begin
|
37
|
+
def test_key_add
|
38
|
+
assert_raises(DeisError) {
|
39
|
+
@client.key_add(nil, nil)
|
40
|
+
}
|
41
|
+
response = @client.key_add(@username, @key)
|
42
|
+
unless @mock
|
43
|
+
assert response["id"]
|
44
|
+
assert response["owner"] == @username
|
45
|
+
assert response["public"] == @key
|
46
|
+
end
|
47
|
+
end
|
48
|
+
=end
|
49
|
+
|
50
|
+
def test_config
|
51
|
+
assert_raises(DeisError) {
|
52
|
+
@client.config_set(nil, nil)
|
53
|
+
}
|
54
|
+
response = @client.app_create(nil)
|
55
|
+
app_name = response["id"]
|
56
|
+
unless @mock
|
57
|
+
assert @client.config_set(app_name, {}).empty?
|
58
|
+
configs = {"HELLO" => "world", "PLATFORM" => "deis"}
|
59
|
+
response = @client.config_set(app_name, configs)
|
60
|
+
assert response["values"].has_key?("HELLO")
|
61
|
+
assert response["values"].has_key?("PLATFORM")
|
62
|
+
assert response["values"].has_value?("world")
|
63
|
+
assert response["values"].has_value?("deis")
|
64
|
+
|
65
|
+
stored_config = @client.config_get(app_name)
|
66
|
+
assert stored_config.has_key?("HELLO")
|
67
|
+
assert stored_config.has_key?("PLATFORM")
|
68
|
+
assert stored_config.has_value?("world")
|
69
|
+
assert stored_config.has_value?("deis")
|
70
|
+
|
71
|
+
response = @client.config_set(app_name, "BUILDPACK_URL" => "https://github.com/AnyPresence/heroku-buildpack-node")
|
72
|
+
assert response["values"].has_key?("BUILDPACK_URL")
|
73
|
+
|
74
|
+
response = @client.app_destroy(app_name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_command_run
|
79
|
+
assert_raises(DeisError) {
|
80
|
+
@client.config_set(nil, nil)
|
81
|
+
}
|
82
|
+
unless @mock
|
83
|
+
response = @client.command_run(@instance_name, "echo stuff")
|
84
|
+
assert response.first == 0
|
85
|
+
assert response.last.strip.end_with? "stuff"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_app_scale
|
90
|
+
assert_raises(DeisError) {
|
91
|
+
@client.app_scale(nil, "nil", "nil")
|
92
|
+
}
|
93
|
+
assert_raises(DeisError) {
|
94
|
+
@client.app_scale("my-app", "proc", 1)
|
95
|
+
}
|
96
|
+
assert_raises(DeisError) {
|
97
|
+
@client.app_scale("my-app", "web", -1)
|
98
|
+
}
|
99
|
+
unless @instance_name.nil?
|
100
|
+
@client.app_scale(@instance_name, "web", 2)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_app_restart
|
105
|
+
assert_raises(DeisError) {
|
106
|
+
@client.app_restart(nil)
|
107
|
+
}
|
108
|
+
unless @instance_name.nil?
|
109
|
+
@client.app_restart(@instance_name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deis-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- AnyPresence
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.6.7
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.6.7
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
description: Deis Platform REST (V1.5) client for Ruby.
|
34
|
+
email: engineering@anypresence.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- ".gitignore"
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- deis_client.gemspec
|
44
|
+
- lib/deis_client.rb
|
45
|
+
- test/test_deis_client.rb
|
46
|
+
homepage: http://rubygems.org/gems/deis_client
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.9.3
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.4.5.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: Deis REST operations in a Ruby gem.
|
70
|
+
test_files: []
|