acquia-cloud 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76d413a96d61a55b3bdd919b882bb1c2a51344e7
4
+ data.tar.gz: a4d6543e4d1c4036c00b5fb9cbde78e2af438929
5
+ SHA512:
6
+ metadata.gz: 70a6e0594f9248b8ba6348bce0c041a0c2ad0e4df6a1bd60493c4ed844d8a9564f06aee35e741194405d52ad665b68eba826f34cf75f3752755c18ea7a247e37
7
+ data.tar.gz: 43c45cbc34be2a07f6745b9e2f40628b313645b2a8c8f66e1d9f12aa4da05ce98c2b188fdef947b34c9b8d11a1bd462944fc1c0a87aa392fd02de775bfc77dd5
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ /pkg
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.2
5
+
6
+ install:
7
+ - bundle install --deployment
8
+ script:
9
+ - bundle exec rake ci
10
+
11
+ cache:
12
+ directories:
13
+ - vendor
14
+
15
+ branches:
16
+ only:
17
+ - master
18
+
19
+ notifications:
20
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec name: 'acquia-cloud'
data/Gemfile.lock ADDED
@@ -0,0 +1,98 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ acquia-cloud (0.1.0.pre)
5
+ faraday (~> 0.9)
6
+ websocket (~> 1.2)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ abstract_type (0.0.7)
12
+ adamantium (0.2.0)
13
+ ice_nine (~> 0.11.0)
14
+ memoizable (~> 0.4.0)
15
+ anima (0.3.0)
16
+ abstract_type (~> 0.0.7)
17
+ adamantium (~> 0.2)
18
+ equalizer (~> 0.0.11)
19
+ ast (2.1.0)
20
+ concord (0.1.5)
21
+ adamantium (~> 0.2.0)
22
+ equalizer (~> 0.0.9)
23
+ diff-lcs (1.2.5)
24
+ equalizer (0.0.11)
25
+ faraday (0.9.2)
26
+ multipart-post (>= 1.2, < 3)
27
+ ice_nine (0.11.1)
28
+ memoizable (0.4.2)
29
+ thread_safe (~> 0.3, >= 0.3.1)
30
+ morpher (0.2.5)
31
+ abstract_type (~> 0.0.7)
32
+ adamantium (~> 0.2.0)
33
+ anima (~> 0.3.0)
34
+ ast (~> 2.1.0)
35
+ concord (~> 0.1.5)
36
+ equalizer (~> 0.0.9)
37
+ ice_nine (~> 0.11.0)
38
+ procto (~> 0.0.2)
39
+ multipart-post (2.0.0)
40
+ mutant (0.8.8)
41
+ abstract_type (~> 0.0.7)
42
+ adamantium (~> 0.2.0)
43
+ anima (~> 0.3.0)
44
+ ast (~> 2.1)
45
+ concord (~> 0.1.5)
46
+ diff-lcs (~> 1.2)
47
+ equalizer (~> 0.0.9)
48
+ ice_nine (~> 0.11.1)
49
+ memoizable (~> 0.4.2)
50
+ morpher (~> 0.2.5)
51
+ parallel (~> 1.3)
52
+ parser (~> 2.2.2)
53
+ procto (~> 0.0.2)
54
+ unparser (~> 0.2.4)
55
+ mutant-rspec (0.8.8)
56
+ mutant (~> 0.8.8)
57
+ rspec-core (>= 3.2.0, < 3.5.0)
58
+ parallel (1.6.1)
59
+ parser (2.2.3.0)
60
+ ast (>= 1.1, < 3.0)
61
+ procto (0.0.2)
62
+ rake (10.4.2)
63
+ rspec (3.4.0)
64
+ rspec-core (~> 3.4.0)
65
+ rspec-expectations (~> 3.4.0)
66
+ rspec-mocks (~> 3.4.0)
67
+ rspec-core (3.4.0)
68
+ rspec-support (~> 3.4.0)
69
+ rspec-expectations (3.4.0)
70
+ diff-lcs (>= 1.2.0, < 2.0)
71
+ rspec-support (~> 3.4.0)
72
+ rspec-mocks (3.4.0)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.4.0)
75
+ rspec-support (3.4.0)
76
+ thread_safe (0.3.5)
77
+ unparser (0.2.4)
78
+ abstract_type (~> 0.0.7)
79
+ adamantium (~> 0.2.0)
80
+ concord (~> 0.1.5)
81
+ diff-lcs (~> 1.2.5)
82
+ equalizer (~> 0.0.9)
83
+ parser (~> 2.2.2)
84
+ procto (~> 0.0.2)
85
+ websocket (1.2.2)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ acquia-cloud!
92
+ mutant (~> 0.8)
93
+ mutant-rspec (~> 0.8)
94
+ rake (~> 10.4)
95
+ rspec (~> 3.3)
96
+
97
+ BUNDLED WITH
98
+ 1.10.6
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015 Matthew Scharley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a
4
+ copy of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the
8
+ Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included
11
+ in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # acquia-cloud
2
+
3
+ [![Build Status](https://travis-ci.org/Equiem/acquia-cloud.svg)](https://travis-ci.org/Equiem/acquia-cloud)
4
+ [![Dependency Status](https://gemnasium.com/Equiem/acquia-cloud.svg)](https://gemnasium.com/Equiem/acquia-cloud)
5
+
6
+ **Source:** [https://github.com/Equiem/acquia-cloud](https://github.com/Equiem/acquia-cloud)
7
+ **Author:** [Equiem](http://equiem.com.au/)
8
+ **Contributors:** [See contributors on GitHub][gh-contrib]
9
+ **Bugs/Support:** [Github Issues][gh-issues]
10
+ **Copyright:** 2015
11
+ **License:** [MIT license][license]
12
+ **Status:** Active
13
+
14
+ ## Synopsis
15
+
16
+ `acquia-cloud` is a Ruby binding for the Acquia Cloud API.
17
+
18
+ ## Installation
19
+
20
+ $ gem install acquia-cloud
21
+
22
+ Or add `gem 'acquia-cloud'` to your Gemfile and update your bundle.
23
+
24
+ ## Usage
25
+
26
+ > TODO: Write this.
27
+
28
+ See also [the Cloud API documentation](https://cloudapi.acquia.com/).
29
+
30
+ [gh-contrib]: https://github.com/Equiem/acquia-cloud/graphs/contributors
31
+ [gh-issues]: https://github.com/Equiem/acquia-cloud/issues
32
+ [license]: https://github.com/Equiem/acquia-cloud/blob/master/LICENSE
data/Rakefile ADDED
@@ -0,0 +1,66 @@
1
+ $:.push File.join(__FILE__, '../lib')
2
+ require 'acquia/cloud/version'
3
+
4
+ def current_gems
5
+ Dir["pkg/acquia-cloud-#{Acquia::Cloud::VERSION}.gem"]
6
+ end
7
+
8
+ namespace :gem do
9
+ desc 'Build gem'
10
+ task :build => [:clean] do
11
+ mkdir 'pkg' unless File.exist? 'pkg'
12
+ sh *%w{gem build acquia-cloud.gemspec}
13
+ Dir['*.gem'].each do |gem|
14
+ mv gem, "pkg/#{gem}"
15
+ end
16
+ end
17
+
18
+ desc 'Install gem'
19
+ task :install => ['gem:build'] do
20
+ sh *%W{gem install pkg/usmu-#{Acquia::Cloud::VERSION}.gem}
21
+ end
22
+
23
+ desc 'Deploy gems to rubygems'
24
+ task :deploy => ['gem:build'] do
25
+ current_gems.each do |gem|
26
+ sh *%W{gem push #{gem}}
27
+ end
28
+ if File.exist? '.git'
29
+ sh *%W{git tag #{Acquia::Cloud::VERSION}}
30
+ sh *%W{git push origin tag #{Acquia::Cloud::VERSION}}
31
+ end
32
+ end
33
+ end
34
+
35
+ task :clean
36
+
37
+ desc 'Run CI tasks.'
38
+ task :ci => [:rspec]
39
+
40
+ desc 'Run all RSpec tests.'
41
+ task :rspec do
42
+ sh 'bundle', 'exec', 'rspec'
43
+ end
44
+
45
+ desc 'Run mutation tests'
46
+ task :mutant, [:target] do |t,args|
47
+ sh 'bundle', 'exec', 'mutant',
48
+ '--include', 'lib',
49
+ '--require', 'acquia/cloud',
50
+ '--use', 'rspec',
51
+ # Interfaces and documentation classes
52
+ # '--ignore-subject', 'Usmu::Deployment::RemoteFileInterface*',
53
+ args[:target] || 'Acquia::Cloud*'
54
+ end
55
+
56
+ desc 'Run a console with our gems available'
57
+ task :console do
58
+ sh 'bundle', 'exec', 'irb', '-r', 'acquia/cloud'
59
+ end
60
+
61
+ namespace :git do
62
+ desc 'Cleanup (delete) all local branches that have already been merged into master (locally)'
63
+ task :cleanup do
64
+ `git branch --merged master`.lines.map(&:chomp).select {|i| i != ' master' && i[0,2] != '* ' }.each {|b| sh "git branch -d #{b.strip}" }
65
+ end
66
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+
3
+ $:.push File.join(__FILE__, '../lib')
4
+ require 'acquia/cloud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'acquia-cloud'
8
+ spec.version = Acquia::Cloud::VERSION
9
+ spec.authors = ['Equiem']
10
+ spec.email = ['sysadmin@equiem.com.au']
11
+ spec.summary = %q{Bindings to the Acquia Cloud API.}
12
+ spec.description = ''
13
+ spec.homepage = 'https://github.com/Equiem/BOTS'
14
+ spec.licenses = ['MIT']
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^spec/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.1')
22
+
23
+ spec.add_dependency 'faraday', '~> 0.9'
24
+ spec.add_dependency 'websocket', '~> 1.2'
25
+
26
+ # Dev stuff.
27
+ spec.add_development_dependency 'rake', '~> 10.4'
28
+ spec.add_development_dependency 'rspec', '~> 3.3'
29
+ spec.add_development_dependency 'mutant', '~> 0.8'
30
+ spec.add_development_dependency 'mutant-rspec', '~> 0.8'
31
+ end
@@ -0,0 +1,41 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module Acquia
5
+ # @see https://cloudapi.acquia.com/
6
+ class Cloud
7
+ attr_reader :api
8
+
9
+ def initialize(args = {})
10
+ @api = Api.new args
11
+ end
12
+
13
+ def sites
14
+ @sites ||= @api.get('/sites').map do |site|
15
+ Site.new(self, site)
16
+ end
17
+ end
18
+
19
+ # @return [Acquia::Cloud::Site]
20
+ def site(name)
21
+ Site.new(self, name).refresh
22
+ end
23
+
24
+ def drushrc
25
+ @api.get '/me/drushrc'
26
+ end
27
+ end
28
+ end
29
+
30
+ %w{
31
+ version
32
+ errors
33
+ api
34
+ database
35
+ environment
36
+ server
37
+ site
38
+ task
39
+ logs/source
40
+ logs/streamer
41
+ }.each {|p| require "acquia/cloud/#{p}" }
@@ -0,0 +1,56 @@
1
+
2
+ module Acquia
3
+ class Cloud
4
+ class Api
5
+ API_VERSION = 'v1'
6
+ BASE_URL = 'https://cloudapi.acquia.com'
7
+
8
+ def initialize(args = {})
9
+ @acquia = Faraday.new(:url => 'https://cloudapi.acquia.com') do |client|
10
+ client.request :url_encoded
11
+ client.adapter Faraday.default_adapter
12
+
13
+ # Log request and response to STDOUT.
14
+ # client.use Faraday::Response::Logger
15
+
16
+ # Raise errors on HTTP error codes.
17
+ client.use Faraday::Response::RaiseError
18
+ end
19
+
20
+ if args[:credentials].nil?
21
+ if ENV['ACQUIA_CLOUD_CREDENTIALS'].nil?
22
+ raise 'Unable to detect your credentials. Please populate ACQUIA_CLOUD_CREDENTIALS with your username and API key.'
23
+ end
24
+
25
+ args[:credentials] = ENV['ACQUIA_CLOUD_CREDENTIALS']
26
+ end
27
+
28
+ credentials = args[:credentials].split(':', 2)
29
+ if credentials.length < 2
30
+ raise 'You must specify both username and API key in credentials.'
31
+ end
32
+ @acquia.basic_auth *credentials
33
+ end
34
+
35
+ def get(url = nil, params = nil, headers = nil, &block)
36
+ request :get, url, params, headers, &block
37
+ end
38
+
39
+
40
+ def post(url = nil, body = nil, headers = nil, &block)
41
+ request :post, url, body.nil? ? body : body.to_json, headers, &block
42
+ end
43
+
44
+ def delete(url = nil, params = nil, headers = nil, &block)
45
+ request :delete, url, params, headers, &block
46
+ end
47
+
48
+ protected
49
+
50
+ def request(method, url = nil, arg2 = nil, headers = nil, &block)
51
+ response = @acquia.method(method).call "/#{API_VERSION}#{url}.json", arg2, headers, &block
52
+ JSON.load(response.body)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ require 'acquia/cloud/entity'
2
+
3
+ module Acquia
4
+ class Cloud
5
+ class Database < Entity
6
+ def initialize(cloud, site, database)
7
+ @cloud = cloud
8
+ @site = site
9
+ @data = database
10
+ @url = "/sites/#{@site}/dbs/#{@data['name']}"
11
+ end
12
+
13
+ def name
14
+ data['name']
15
+ end
16
+
17
+ def backup_on(environment)
18
+ @cloud.site(@site).environment(environment).backup_database(name)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module Acquia
3
+ class Cloud
4
+ class Entity
5
+ attr_accessor :url
6
+
7
+ def refresh
8
+ @data = @cloud.api.get url
9
+ self
10
+ end
11
+
12
+ protected
13
+
14
+ def data
15
+ @data || (refresh && @data)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,80 @@
1
+ require 'acquia/cloud/entity'
2
+
3
+ module Acquia
4
+ class Cloud
5
+ class Environment < Entity
6
+ def initialize(cloud, site, environment)
7
+ @cloud = cloud
8
+ @site = site
9
+ @data = environment
10
+ @url = "/sites/#{@site}/envs/#{@data['name']}"
11
+ end
12
+
13
+ def name
14
+ data['name']
15
+ end
16
+
17
+ def vcs_path
18
+ data['vcs_path']
19
+ end
20
+
21
+ def ssh_host
22
+ data['ssh_host']
23
+ end
24
+
25
+ def db_clusters
26
+ data['db_clusters']
27
+ end
28
+
29
+ def default_domain
30
+ data['default_domain']
31
+ end
32
+
33
+ def unix_username
34
+ data['unix_username']
35
+ end
36
+
37
+ # new_vcs_path should start with 'tags/' or 'heads/' to distinguish
38
+ # between tags or branches.
39
+ def deploy_path(new_vcs_path)
40
+ task = @cloud.api.post("#{@url}/code-deploy") do |response|
41
+ response.params['path'] = new_vcs_path
42
+ end
43
+
44
+ Task.new(@cloud, @site, task)
45
+ end
46
+
47
+ def backup_database(database_name)
48
+ task = @cloud.api.post("#{@url}/dbs/#{database_name}/backups")
49
+ Task.new @cloud, @site, task
50
+ end
51
+
52
+ def logstream
53
+ response = @cloud.api.get("#{@url}/logstream")
54
+ Logs::Streamer.new(response['url'], JSON.parse(response['msg']))
55
+ end
56
+
57
+ def servers
58
+ @cloud.api.get("#{url}/servers").map do |server|
59
+ Server.new(@cloud, @site, name, server)
60
+ end
61
+ end
62
+
63
+ def server(server)
64
+ Server.new(@cloud, @site, name, {'name' => server}).refresh
65
+ end
66
+
67
+ def database_servers
68
+ servers.select &:database?
69
+ end
70
+
71
+ def varnish_servers
72
+ servers.select &:varnish?
73
+ end
74
+
75
+ def web_servers
76
+ servers.select &:web?
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,8 @@
1
+ module Acquia
2
+ class Cloud
3
+ class StreamerError < ::RuntimeError; end
4
+ class StreamerConnectionError < StreamerError; end
5
+ class StreamerRemoteError < StreamerError; end
6
+ class StreamerUnrecognisedCommandError < StreamerError; end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ module Acquia
2
+ class Cloud
3
+ module Logs
4
+ class Source
5
+ attr_reader :server
6
+ attr_reader :type
7
+ attr_reader :display_type
8
+
9
+ def initialize(server, type, display_type)
10
+ @server = server
11
+ @type = type
12
+ @display_type = display_type
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,147 @@
1
+ require 'socket'
2
+ require 'websocket'
3
+ require 'json'
4
+ require 'uri'
5
+
6
+ module Acquia
7
+ class Cloud
8
+ module Logs
9
+ # https://github.com/acquia/logstream/blob/master/README.md
10
+ class Streamer
11
+ # Try to retrieve 16KB blocks from the socket.
12
+ RECV_LENGTH = 16 * 1024
13
+
14
+ attr_reader :remote_server
15
+
16
+ def initialize(url, message)
17
+ @url = url
18
+ @message = message
19
+ @logs = []
20
+ @available = []
21
+ @enabled_types = []
22
+ end
23
+
24
+ def debug
25
+ @debug = true
26
+ end
27
+
28
+ def connect
29
+ raise StreamerConnectionError, 'Already connected.' unless @socket.nil?
30
+
31
+ @handshake = ::WebSocket::Handshake::Client.new url: @url
32
+ uri = ::URI.parse @url
33
+ @socket = TCPSocket.new uri.host, uri.port || 80
34
+ @socket.print @handshake.to_s
35
+
36
+ until @handshake.finished?
37
+ @handshake << @socket.gets
38
+ end
39
+ raise StreamerConnectionError, "Couldn't get a valid response while connecting to the remote server: #{@url}" unless @handshake.valid?
40
+ @incoming = WebSocket::Frame::Incoming::Client.new(version: @handshake.version)
41
+
42
+ # Initial authentication
43
+ send @message
44
+ end
45
+
46
+ def close
47
+ @socket.close
48
+ end
49
+
50
+ def sources
51
+ update
52
+ @available.clone
53
+ end
54
+
55
+ def enable(opts = {})
56
+ if opts[:source]
57
+ opts[:server] = opts[:source].server
58
+ opts[:type] = opts[:source].type
59
+ end
60
+
61
+ send({
62
+ cmd: 'enable',
63
+ server: opts[:server],
64
+ type: opts[:type],
65
+ })
66
+ end
67
+
68
+ def enable_type(type)
69
+ @available.each do |source|
70
+ enable source: source
71
+ end
72
+ @enabled_types << type
73
+ end
74
+
75
+ def disable(opts = {})
76
+ if opts[:source]
77
+ opts[:server] = opts[:source].server
78
+ opts[:type] = opts[:source].type
79
+ end
80
+
81
+ send({
82
+ cmd: 'disable',
83
+ server: opts[:server],
84
+ type: opts[:type],
85
+ })
86
+ end
87
+
88
+ def disable_type(type)
89
+ @available.each do |source|
90
+ disable source: source
91
+ end
92
+ @enabled_types.delete type
93
+ end
94
+
95
+ def each_log
96
+ update
97
+ until @logs.empty?
98
+ yield @logs.shift
99
+ end
100
+ end
101
+
102
+ protected
103
+
104
+ def send(message)
105
+ message = message.to_json
106
+ STDERR.puts "-> #{message}" if @debug
107
+ frame = ::WebSocket::Frame::Outgoing::Client.new(version: @handshake.version, type: 'text', data: message)
108
+ @socket.print frame.to_s
109
+ end
110
+
111
+ def update
112
+ # Read as much as possible
113
+ @incoming << @socket.read_nonblock(RECV_LENGTH) while true
114
+ rescue ::IO::WaitReadable
115
+ loop do
116
+ msg = @incoming.next
117
+ break unless msg
118
+ STDERR.puts "<- #{msg}" if @debug
119
+
120
+ msg = JSON.parse(msg.data)
121
+ case msg['cmd']
122
+ when 'connected'
123
+ @remote_server = msg['server'] if msg['server'].start_with? 'logstream-api'
124
+ when 'success'
125
+ # Congratulations!
126
+ when 'error'
127
+ raise StreamerRemoteError, "#{msg['code']}: #{msg['description']} during #{msg['during'].inspect}"
128
+ when 'available'
129
+ source = Source.new(msg['server'], msg['type'], msg['display_type'])
130
+ @available << source
131
+ enable source: source if @enabled_types.include? source.type
132
+ when 'line'
133
+ @logs << msg
134
+ else
135
+ if @debug
136
+ STDERR.puts "Received unknown command: #{msg['cmd']}"
137
+ STDERR.puts msg.inspect
138
+ else
139
+ raise StreamerUnrecognisedCommandError, "Unrecognised command: #{msg['cmd']}\n#{msg.inspect}"
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,62 @@
1
+ require 'acquia/cloud/entity'
2
+
3
+ module Acquia
4
+ class Cloud
5
+ class Server < Entity
6
+ def initialize(cloud, site, env, server)
7
+ @cloud = cloud
8
+ @site = site
9
+ @env = env
10
+ @data = server
11
+ @url = "/sites/#{@site}/envs/#{env}/servers/#{@data['name']}"
12
+ end
13
+
14
+ def name
15
+ data['name']
16
+ end
17
+
18
+ def fqdn
19
+ data['fqdn']
20
+ end
21
+
22
+ def ami_type
23
+ data['ami_type']
24
+ end
25
+
26
+ def ec2_region
27
+ data['ec2_region']
28
+ end
29
+
30
+ def ec2_availability_zone
31
+ data['ec2_availability_zone']
32
+ end
33
+
34
+ def services
35
+ data['services']
36
+ end
37
+
38
+ def varnish?
39
+ services.has_key? 'varnish'
40
+ end
41
+
42
+ def web?
43
+ services.has_key? 'web'
44
+ end
45
+
46
+ def database?
47
+ services.has_key? 'database'
48
+ end
49
+
50
+ def php_procs(memory_limit, apc_shm)
51
+ return nil unless web?
52
+
53
+ values = @cloud.api.get("#{url}/php-procs") do |response|
54
+ response.params['memory_limits[]'] = memory_limit
55
+ response.params['apc_shm[]'] = apc_shm
56
+ end
57
+
58
+ values['memory_limit'][memory_limit]['apc_shm'][apc_shm]['php_procs']
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,73 @@
1
+ require 'acquia/cloud/entity'
2
+
3
+ module Acquia
4
+ class Cloud
5
+ class Site < Entity
6
+ attr_reader :name
7
+
8
+ def initialize(cloud, name)
9
+ @cloud = cloud
10
+ @name = name
11
+ @url = "/sites/#{name}"
12
+ end
13
+
14
+ def name
15
+ data['name']
16
+ end
17
+
18
+ def vcs_type
19
+ data['vcs_type'].to_sym
20
+ end
21
+
22
+ def vcs_url
23
+ data['vcs_url']
24
+ end
25
+
26
+ def production_mode
27
+ data['production_mode'].to_i != 0
28
+ end
29
+
30
+ def unix_username
31
+ data['unix_username']
32
+ end
33
+
34
+ def title
35
+ data['title']
36
+ end
37
+
38
+ def uuid
39
+ data['uuid']
40
+ end
41
+
42
+ def environments
43
+ @cloud.api.get("#{@url}/envs").map do |environment|
44
+ Environment.new(@cloud, @name, environment)
45
+ end
46
+ end
47
+
48
+ def environment(name)
49
+ Environment.new(@cloud, @name, {'name' => name}).refresh
50
+ end
51
+
52
+ def databases
53
+ @cloud.api.get("#{@url}/dbs").map do |db|
54
+ Database.new(@cloud, @name, db)
55
+ end
56
+ end
57
+
58
+ def database(name)
59
+ Database.new(@cloud, @name, {'name' => name}).refresh
60
+ end
61
+
62
+ def tasks
63
+ @cloud.api.get("#{@url}/tasks").map do |task|
64
+ Task.new(@cloud, @name, task)
65
+ end
66
+ end
67
+
68
+ def task(id)
69
+ Task.new(@cloud, @name, {'id' => id}).refresh
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,62 @@
1
+ require 'acquia/cloud/entity'
2
+
3
+ module Acquia
4
+ class Cloud
5
+ class Task < Entity
6
+ def initialize(cloud, site, task)
7
+ @cloud = cloud
8
+ @site = site
9
+ @data = task
10
+ @url = "/sites/#{@site}/tasks/#{@data['id']}"
11
+ end
12
+
13
+ def id
14
+ data['id']
15
+ end
16
+
17
+ def queue
18
+ data['queue']
19
+ end
20
+
21
+ def state
22
+ data['state'].to_sym
23
+ end
24
+
25
+ def description
26
+ data['description']
27
+ end
28
+
29
+ def created
30
+ Time.at(data['created'].to_i)
31
+ end
32
+
33
+ def started
34
+ Time.at(data['started'].to_i)
35
+ end
36
+
37
+ def completed
38
+ Time.at(data['completed'].to_i)
39
+ end
40
+
41
+ def logs
42
+ data['logs']
43
+ end
44
+
45
+ def wait_for_completion(message = nil)
46
+ print message if message
47
+ loop do
48
+ # This will take several minutes, don't spam Acquia too hard while waiting.
49
+ sleep 15
50
+ print '.' if message
51
+ refresh
52
+ unless [:started].include? state
53
+ puts if message
54
+ break
55
+ end
56
+ end
57
+
58
+ self
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module Acquia
2
+ class Cloud
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acquia-cloud
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Equiem
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: websocket
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mutant
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mutant-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
+ description: ''
98
+ email:
99
+ - sysadmin@equiem.com.au
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".ruby-version"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - Gemfile.lock
109
+ - LICENSE
110
+ - README.md
111
+ - Rakefile
112
+ - acquia-cloud.gemspec
113
+ - lib/acquia/cloud.rb
114
+ - lib/acquia/cloud/api.rb
115
+ - lib/acquia/cloud/database.rb
116
+ - lib/acquia/cloud/entity.rb
117
+ - lib/acquia/cloud/environment.rb
118
+ - lib/acquia/cloud/errors.rb
119
+ - lib/acquia/cloud/logs/source.rb
120
+ - lib/acquia/cloud/logs/streamer.rb
121
+ - lib/acquia/cloud/server.rb
122
+ - lib/acquia/cloud/site.rb
123
+ - lib/acquia/cloud/task.rb
124
+ - lib/acquia/cloud/version.rb
125
+ homepage: https://github.com/Equiem/BOTS
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '2.1'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.6
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Bindings to the Acquia Cloud API.
149
+ test_files: []