acquia-cloud 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []