moonshot 0.7.3 → 0.7.4

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/moonshot.rb +7 -0
  3. data/lib/plugins/backup.rb +174 -0
  4. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4efa7393335490c5e80a03e6f3c733727c75acdf
4
- data.tar.gz: 185c228d9dcec000b92fafca815cf9ac9b36ebf4
3
+ metadata.gz: 207bc0ba79e75fe91db4654c343970fa6d902503
4
+ data.tar.gz: d3dba39637da2478ea33d114ded4d5d386a6df38
5
5
  SHA512:
6
- metadata.gz: 17624a530e39bbe1179a776c082d9f1b4e5d2b8ea68dd0c0fc811d3767b5a4b014721b6b41d7253ba973d33772ee1cfb2b4b7c9345bfeef5625dcbeb9e045646
7
- data.tar.gz: ca1d90df3feba59452c6d0a5c6bf63467c73d7fc009c2fda144cfce826a31e7f6184c1042b6bfbf99256baaab37ae9a4cabcb8cd5de03e162c2fd5f21d0cd63f
6
+ metadata.gz: a85739273ac8d835db5402aa3ebf96c290e961c2ac4a4af6fa6825a99172dc0cec56d6d9c5d5a762cb4523e77d0ec5d76fac4f5422db7188b69c18b94f85a025
7
+ data.tar.gz: 3c51fe1fc53305da957c7bca13c5dc041d2e2cff497f2b93ed7f7dd8b28c9fe8a8048b5f17a89241a046557ba55e5e69885c918de1d84f07e6984518cec86efd
data/lib/moonshot.rb CHANGED
@@ -10,6 +10,8 @@ module Moonshot
10
10
  end
11
11
  module DeploymentMechanism # rubocop:disable Documentation
12
12
  end
13
+ module Plugins # rubocop:disable Documentation
14
+ end
13
15
  end
14
16
 
15
17
  [
@@ -39,3 +41,8 @@ end
39
41
  'build_mechanism/version_proxy',
40
42
  'deployment_mechanism/code_deploy'
41
43
  ].each { |f| require_relative "moonshot/#{f}" }
44
+
45
+ # Bundled plugins
46
+ [
47
+ 'backup'
48
+ ].each { |p| require_relative "plugins/#{p}" }
@@ -0,0 +1,174 @@
1
+ require 'rubygems/package'
2
+ require 'zlib'
3
+ require_relative '../moonshot/creds_helper'
4
+
5
+ module Moonshot
6
+ module Plugins
7
+ # Moonshot plugin class for deflating and uploading files on given hooks
8
+ class Backup # rubocop:disable Metrics/ClassLength
9
+ include Moonshot::CredsHelper
10
+
11
+ attr_accessor :bucket,
12
+ :buckets,
13
+ :files,
14
+ :hooks,
15
+ :target_name
16
+
17
+ def initialize
18
+ yield self if block_given?
19
+ raise ArgumentError \
20
+ if @files.nil? || @files.empty? || @hooks.nil? || !(@bucket.nil? ^ @buckets.nil?)
21
+
22
+ @target_name ||= '%{app_name}_%{timestamp}_%{user}.tar.gz'
23
+ end
24
+
25
+ # Factory method to create preconfigured Backup plugins. Uploads current
26
+ # template and parameter files.
27
+ # @param backup [String] target bucket name
28
+ # @return [Backup] configured backup object
29
+ def self.to_bucket(bucket)
30
+ raise ArgumentError if bucket.nil? || bucket.empty?
31
+ Moonshot::Plugins::Backup.new do |b|
32
+ b.bucket = bucket
33
+ b.files = [
34
+ 'cloud_formation/%{app_name}.json',
35
+ 'cloud_formation/parameters/%{stack_name}.yml'
36
+ ]
37
+ b.hooks = [:post_create, :post_update]
38
+ end
39
+ end
40
+
41
+ # Main worker method, creates a tarball of the given files, and uploads
42
+ # to an S3 bucket.
43
+ #
44
+ # @param resources [Resources] injected Moonshot resources
45
+ def backup(resources) # rubocop:disable Metrics/AbcSize
46
+ raise ArgumentError if resources.nil?
47
+
48
+ @app_name = resources.stack.app_name
49
+ @stack_name = resources.stack.name
50
+ @target_name = render(@target_name)
51
+ @target_bucket = define_bucket
52
+
53
+ return if @target_bucket.nil?
54
+
55
+ resources.ilog.start("#{log_message} in progress.") do |s|
56
+ begin
57
+ tar_out = tar(@files)
58
+ zip_out = zip(tar_out)
59
+ upload(zip_out)
60
+
61
+ s.success("#{log_message} succeeded.")
62
+ rescue StandardError => e
63
+ s.failure("#{log_message} failed: #{e}")
64
+ ensure
65
+ tar_out.close unless tar_out.nil?
66
+ zip_out.close unless zip_out.nil?
67
+ end
68
+ end
69
+ end
70
+
71
+ # Dynamically responding to hooks supplied in the constructor
72
+ def method_missing(method_name, *args, &block)
73
+ @hooks.include?(method_name) ? backup(*args) : super
74
+ end
75
+
76
+ def respond_to?(method_name, include_private = false)
77
+ @hooks.include?(method_name) || super
78
+ end
79
+
80
+ private
81
+
82
+ attr_accessor :app_name,
83
+ :stack_name,
84
+ :target_bucket
85
+
86
+ # Create a tar archive in memory, returning the IO object pointing at the
87
+ # beginning of the archive.
88
+ #
89
+ # @param target_files [Array<String>]
90
+ # @return tar_stream [IO]
91
+ def tar(target_files)
92
+ tar_stream = StringIO.new
93
+ Gem::Package::TarWriter.new(tar_stream) do |writer|
94
+ target_files.each do |file|
95
+ file = render(file)
96
+
97
+ writer.add_file(File.basename(file), 0644) do |io|
98
+ File.open(file, 'r') { |f| io.write(f.read) }
99
+ end
100
+ end
101
+ end
102
+ tar_stream.seek(0)
103
+ tar_stream
104
+ end
105
+
106
+ # Create a zip archive in memory, returning the IO object pointing at the
107
+ # beginning of the zipfile.
108
+ #
109
+ # @param io_tar [IO] tar stream
110
+ # @return zip_stream [IO] IO stream of zipped file
111
+ def zip(io_tar)
112
+ zip_stream = StringIO.new
113
+ Zlib::GzipWriter.wrap(zip_stream) do |gz|
114
+ gz.write(io_tar.read)
115
+ gz.finish
116
+ end
117
+ zip_stream.seek(0)
118
+ zip_stream
119
+ end
120
+
121
+ # Uploads an object from the passed IO stream to the specified bucket
122
+ #
123
+ # @param io_zip [IO] tar stream
124
+ def upload(io_zip)
125
+ s3_client.put_object(
126
+ acl: 'private',
127
+ bucket: @target_bucket,
128
+ key: @target_name,
129
+ body: io_zip
130
+ )
131
+ end
132
+
133
+ # Renders string with the specified placeholders
134
+ #
135
+ # @param io_zip [String] raw string with placeholders
136
+ # @return [String] rendered string
137
+ def render(placeholder)
138
+ format(
139
+ placeholder,
140
+ app_name: @app_name,
141
+ stack_name: @stack_name,
142
+ timestamp: Time.now.to_i.to_s,
143
+ user: ENV['USER']
144
+ )
145
+ end
146
+
147
+ def log_message
148
+ "Uploading '#{@target_name}' to '#{@target_bucket}'"
149
+ end
150
+
151
+ def iam_account
152
+ iam_client.list_account_aliases.account_aliases.first
153
+ end
154
+
155
+ def define_bucket
156
+ case
157
+ # returning already calculated bucket name
158
+ when @target_bucket
159
+ @target_bucket
160
+ # single bucket for all accounts
161
+ when @bucket
162
+ @bucket
163
+ # calculating bucket based on account name
164
+ when @buckets
165
+ bucket_by_account(iam_account)
166
+ end
167
+ end
168
+
169
+ def bucket_by_account(account)
170
+ @buckets[account]
171
+ end
172
+ end
173
+ end
174
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moonshot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cloud Engineering <engineering@acquia.com>
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-10 00:00:00.000000000 Z
11
+ date: 2016-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -213,6 +213,7 @@ files:
213
213
  - lib/moonshot/stack_parameter_printer.rb
214
214
  - lib/moonshot/stack_template.rb
215
215
  - lib/moonshot/unicode_table.rb
216
+ - lib/plugins/backup.rb
216
217
  homepage: https://github.com/acquia/moonshot
217
218
  licenses:
218
219
  - Apache-2.0