heirloom 0.5.0rc2 → 0.5.0rc3
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/CHANGELOG +10 -2
- data/lib/heirloom.rb +1 -1
- data/lib/heirloom/archive.rb +1 -5
- data/lib/heirloom/archive/builder.rb +16 -13
- data/lib/heirloom/archive/downloader.rb +27 -19
- data/lib/heirloom/archive/writer.rb +52 -0
- data/lib/heirloom/cipher.rb +2 -0
- data/lib/heirloom/cipher/data.rb +33 -0
- data/lib/heirloom/cipher/file.rb +41 -0
- data/lib/heirloom/cli/authorize.rb +4 -2
- data/lib/heirloom/cli/build.rb +17 -12
- data/lib/heirloom/cli/destroy.rb +5 -3
- data/lib/heirloom/cli/download.rb +15 -10
- data/lib/heirloom/cli/list.rb +7 -5
- data/lib/heirloom/cli/shared.rb +14 -4
- data/lib/heirloom/cli/show.rb +6 -4
- data/lib/heirloom/cli/update.rb +4 -2
- data/lib/heirloom/config.rb +1 -1
- data/lib/heirloom/directory/directory.rb +23 -8
- data/lib/heirloom/directory/git_directory.rb +10 -1
- data/lib/heirloom/version.rb +1 -1
- data/spec/archive/builder_spec.rb +55 -50
- data/spec/archive/downloader_spec.rb +91 -37
- data/spec/archive/writer_spec.rb +51 -0
- data/spec/archive_spec.rb +0 -11
- data/spec/aws/simpledb_spec.rb +2 -2
- data/spec/cipher/data_spec.rb +56 -0
- data/spec/cipher/file_spec.rb +27 -0
- data/spec/cli/build_spec.rb +3 -3
- data/spec/cli/download_spec.rb +4 -2
- data/spec/cli/shared_spec.rb +12 -5
- data/spec/config_spec.rb +2 -2
- data/spec/directory/directory_spec.rb +39 -10
- data/spec/directory/git_directory_spec.rb +29 -15
- metadata +23 -20
- data/lib/heirloom/archive/extracter.rb +0 -38
- data/lib/heirloom/misc.rb +0 -1
- data/lib/heirloom/misc/tmp.rb +0 -12
- data/spec/archive/extracter_spec.rb +0 -21
- data/spec/misc/tmp_spec.rb +0 -19
data/CHANGELOG
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
## v0.5.0:
|
|
2
2
|
|
|
3
|
-
*
|
|
3
|
+
* Verify domain exists for all cmds except build & download
|
|
4
4
|
* Removing requirement to check simpledb on download.
|
|
5
|
-
* Adding requirement base_prefix on download.
|
|
5
|
+
* Adding requirement for base_prefix on download.
|
|
6
6
|
* Fix error when .heirloom.yml does not exist.
|
|
7
7
|
* Refactor cli option validation
|
|
8
8
|
* Refactor cli specs
|
|
9
9
|
* Add -x to download to extract heirloom to given output path
|
|
10
10
|
* Verify -o specified in download is a directory
|
|
11
|
+
* Requiring -d for builds (will no longer default to .)
|
|
12
|
+
* Remove new lines from values of git comments
|
|
13
|
+
* Verify directory given at build is a directory
|
|
14
|
+
* Support archiving directories outside the cwd.
|
|
15
|
+
* Fixed bug in git repo verification on build.
|
|
16
|
+
* Added support for encryption
|
|
17
|
+
* Removed short name and changed long name for AWS CLI Creds
|
|
18
|
+
* Adding encrypted attribute by default
|
|
11
19
|
|
|
12
20
|
## v0.4.0:
|
|
13
21
|
|
data/lib/heirloom.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
require "heirloom/misc"
|
|
2
1
|
require "heirloom/config"
|
|
3
2
|
require "heirloom/acl"
|
|
4
3
|
require "heirloom/aws"
|
|
5
4
|
require "heirloom/logger"
|
|
6
5
|
require "heirloom/archive"
|
|
7
6
|
require "heirloom/directory"
|
|
7
|
+
require "heirloom/cipher"
|
|
8
8
|
require "heirloom/uploader"
|
|
9
9
|
require "heirloom/downloader"
|
|
10
10
|
require "heirloom/destroyer"
|
data/lib/heirloom/archive.rb
CHANGED
|
@@ -4,7 +4,7 @@ require 'heirloom/archive/builder.rb'
|
|
|
4
4
|
require 'heirloom/archive/updater.rb'
|
|
5
5
|
require 'heirloom/archive/uploader.rb'
|
|
6
6
|
require 'heirloom/archive/downloader.rb'
|
|
7
|
-
require 'heirloom/archive/
|
|
7
|
+
require 'heirloom/archive/writer.rb'
|
|
8
8
|
require 'heirloom/archive/authorizer.rb'
|
|
9
9
|
require 'heirloom/archive/destroyer.rb'
|
|
10
10
|
require 'heirloom/archive/verifier.rb'
|
|
@@ -68,10 +68,6 @@ module Heirloom
|
|
|
68
68
|
lister.list(limit)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def cleanup
|
|
72
|
-
builder.cleanup
|
|
73
|
-
end
|
|
74
|
-
|
|
75
71
|
def regions
|
|
76
72
|
reader.regions
|
|
77
73
|
end
|
|
@@ -18,12 +18,15 @@ module Heirloom
|
|
|
18
18
|
|
|
19
19
|
def build(args)
|
|
20
20
|
@source = args[:directory] ||= '.'
|
|
21
|
+
@secret = args[:secret]
|
|
21
22
|
|
|
22
23
|
directory = Directory.new :path => @source,
|
|
23
24
|
:exclude => args[:exclude],
|
|
24
25
|
:config => @config
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
unless directory.build_artifact_from_directory :secret => @secret
|
|
28
|
+
return false
|
|
29
|
+
end
|
|
27
30
|
|
|
28
31
|
@local_build = directory.local_build
|
|
29
32
|
|
|
@@ -36,11 +39,6 @@ module Heirloom
|
|
|
36
39
|
@local_build
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
def cleanup
|
|
40
|
-
@logger.info "Cleaning up local build #{@local_build}."
|
|
41
|
-
File.delete @local_build
|
|
42
|
-
end
|
|
43
|
-
|
|
44
42
|
private
|
|
45
43
|
|
|
46
44
|
def add_git_commit
|
|
@@ -49,14 +47,14 @@ module Heirloom
|
|
|
49
47
|
if commit
|
|
50
48
|
add_git_commit_to_artifact_record commit
|
|
51
49
|
else
|
|
52
|
-
@logger.warn "Could not
|
|
50
|
+
@logger.warn "Could not load Git sha '#{@id}' in '#{@source}'."
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
54
|
def add_git_commit_to_artifact_record(commit)
|
|
57
55
|
attributes = { 'sha' => @id,
|
|
58
56
|
'abbreviated_sha' => commit.id_abbrev,
|
|
59
|
-
'message' => commit.message,
|
|
57
|
+
'message' => commit.message.gsub("\n"," "),
|
|
60
58
|
'author' => commit.author.name }
|
|
61
59
|
|
|
62
60
|
attributes.each_pair do |k, v|
|
|
@@ -67,15 +65,16 @@ module Heirloom
|
|
|
67
65
|
end
|
|
68
66
|
|
|
69
67
|
def create_artifact_record
|
|
70
|
-
attributes = { 'built_by'
|
|
71
|
-
'built_at'
|
|
72
|
-
'
|
|
68
|
+
attributes = { 'built_by' => "#{user}@#{hostname}",
|
|
69
|
+
'built_at' => Time.now.utc.iso8601,
|
|
70
|
+
'encrypted' => encrypted?,
|
|
71
|
+
'id' => @id }
|
|
73
72
|
@logger.info "Create artifact record #{@id}."
|
|
74
73
|
sdb.put_attributes @domain, @id, attributes
|
|
75
74
|
end
|
|
76
75
|
|
|
77
|
-
def
|
|
78
|
-
@
|
|
76
|
+
def encrypted?
|
|
77
|
+
@secret != nil
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
def user
|
|
@@ -86,5 +85,9 @@ module Heirloom
|
|
|
86
85
|
Socket.gethostname
|
|
87
86
|
end
|
|
88
87
|
|
|
88
|
+
def sdb
|
|
89
|
+
@sdb ||= AWS::SimpleDB.new :config => @config
|
|
90
|
+
end
|
|
91
|
+
|
|
89
92
|
end
|
|
90
93
|
end
|
|
@@ -2,8 +2,6 @@ module Heirloom
|
|
|
2
2
|
|
|
3
3
|
class Downloader
|
|
4
4
|
|
|
5
|
-
include Heirloom::Misc::Tmp
|
|
6
|
-
|
|
7
5
|
def initialize(args)
|
|
8
6
|
@config = args[:config]
|
|
9
7
|
@name = args[:name]
|
|
@@ -12,31 +10,34 @@ module Heirloom
|
|
|
12
10
|
end
|
|
13
11
|
|
|
14
12
|
def download(args)
|
|
15
|
-
region = args[:region]
|
|
16
|
-
base_prefix = args[:base_prefix]
|
|
13
|
+
@region = args[:region]
|
|
14
|
+
@base_prefix = args[:base_prefix]
|
|
17
15
|
extract = args[:extract]
|
|
16
|
+
secret = args[:secret]
|
|
18
17
|
output = args[:output] ||= './'
|
|
19
18
|
|
|
19
|
+
@logger.info "Downloading s3://#{bucket}/#{key} from #{@region}."
|
|
20
|
+
|
|
20
21
|
s3_downloader = Downloader::S3.new :config => @config,
|
|
21
22
|
:logger => @logger,
|
|
22
|
-
:region => region
|
|
23
|
+
:region => @region
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
raw_archive = s3_downloader.download_file :bucket => bucket,
|
|
26
|
+
:key => key
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
:key => key
|
|
28
|
+
archive = cipher_data.decrypt_data :data => raw_archive,
|
|
29
|
+
:secret => secret
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
File.open(output_file, 'w') { |local_file| local_file.write archive }
|
|
37
|
-
end
|
|
31
|
+
return false unless archive
|
|
32
|
+
|
|
33
|
+
return false unless writer.save_archive :archive => archive,
|
|
34
|
+
:output => output,
|
|
35
|
+
:file => file,
|
|
36
|
+
:extract => extract
|
|
38
37
|
|
|
39
38
|
@logger.info "Download complete."
|
|
39
|
+
|
|
40
|
+
output
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
private
|
|
@@ -49,9 +50,16 @@ module Heirloom
|
|
|
49
50
|
"#{@name}/#{file}"
|
|
50
51
|
end
|
|
51
52
|
|
|
52
|
-
def
|
|
53
|
-
"#{
|
|
53
|
+
def bucket
|
|
54
|
+
"#{@base_prefix}-#{@region}"
|
|
54
55
|
end
|
|
55
56
|
|
|
57
|
+
def writer
|
|
58
|
+
@writer ||= Writer.new :config => @config
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def cipher_data
|
|
62
|
+
@cipher_data ||= Cipher::Data.new :config => @config
|
|
63
|
+
end
|
|
56
64
|
end
|
|
57
65
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Heirloom
|
|
2
|
+
class Writer
|
|
3
|
+
|
|
4
|
+
def initialize(args)
|
|
5
|
+
@config = args[:config]
|
|
6
|
+
@logger = @config.logger
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def save_archive(args)
|
|
10
|
+
@output = args[:output]
|
|
11
|
+
@file = args[:file]
|
|
12
|
+
@archive = args[:archive]
|
|
13
|
+
@extract = args[:extract]
|
|
14
|
+
|
|
15
|
+
@extract ? extract_archive : write_archive
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def extract_archive
|
|
21
|
+
@tmp_archive = Tempfile.new('archive.tar.gz').path
|
|
22
|
+
|
|
23
|
+
create_tmp_archive
|
|
24
|
+
extract_tmp_archive
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def write_archive
|
|
28
|
+
output_file = File.join @output, @file
|
|
29
|
+
@logger.info "Writing archive to '#{output_file}'."
|
|
30
|
+
File.open(output_file, 'w') { |local_file| local_file.write @archive }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def create_tmp_archive
|
|
34
|
+
File.open(@tmp_archive, 'w') { |local_file| local_file.write @archive }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def extract_tmp_archive
|
|
38
|
+
@logger.info "Extracting archive to '#{@output}'."
|
|
39
|
+
cmd = "tar xzf #{@tmp_archive} -C #{@output}"
|
|
40
|
+
@logger.debug "Executing '#{cmd}'."
|
|
41
|
+
`#{cmd}`
|
|
42
|
+
if $?.success?
|
|
43
|
+
@logger.debug "Archive succesfully extracted."
|
|
44
|
+
true
|
|
45
|
+
else
|
|
46
|
+
@logger.error "Error extracting archive."
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
3
|
+
module Heirloom
|
|
4
|
+
module Cipher
|
|
5
|
+
class Data
|
|
6
|
+
|
|
7
|
+
def initialize(args)
|
|
8
|
+
@config = args[:config]
|
|
9
|
+
@logger = @config.logger
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def decrypt_data(args)
|
|
13
|
+
data = args[:data]
|
|
14
|
+
secret = args[:secret]
|
|
15
|
+
|
|
16
|
+
return data unless secret
|
|
17
|
+
|
|
18
|
+
@logger.info "Secret provided. Decrypting archive."
|
|
19
|
+
|
|
20
|
+
@aes = OpenSSL::Cipher::AES256.new(:CBC)
|
|
21
|
+
@aes.decrypt
|
|
22
|
+
@aes.key = secret
|
|
23
|
+
@aes.iv = data.slice!(0,16)
|
|
24
|
+
begin
|
|
25
|
+
@aes.update(data) + @aes.final
|
|
26
|
+
rescue OpenSSL::Cipher::CipherError => e
|
|
27
|
+
@logger.error "Unable to decrypt archive: '#{e.message}'"
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
|
|
4
|
+
module Heirloom
|
|
5
|
+
module Cipher
|
|
6
|
+
class File
|
|
7
|
+
|
|
8
|
+
def initialize(args)
|
|
9
|
+
@config = args[:config]
|
|
10
|
+
@aes = OpenSSL::Cipher::AES256.new(:CBC)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def encrypt_file(args)
|
|
14
|
+
file = args[:file]
|
|
15
|
+
secret = args[:secret]
|
|
16
|
+
output = Tempfile.new('archive.tar.gz.enc')
|
|
17
|
+
iv = @aes.random_iv
|
|
18
|
+
|
|
19
|
+
@aes.encrypt
|
|
20
|
+
@aes.iv = iv
|
|
21
|
+
@aes.key = secret
|
|
22
|
+
|
|
23
|
+
# Need to refactor to be less complex
|
|
24
|
+
# Additionally tests to do fully cover logic
|
|
25
|
+
::File.open(output,'w') do |enc|
|
|
26
|
+
enc << iv
|
|
27
|
+
::File.open(file) do |f|
|
|
28
|
+
loop do
|
|
29
|
+
r = f.read(4096)
|
|
30
|
+
break unless r
|
|
31
|
+
enc << @aes.update(r)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
enc << @aes.final
|
|
35
|
+
end
|
|
36
|
+
output.path
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -45,11 +45,13 @@ EOS
|
|
|
45
45
|
:multi => true
|
|
46
46
|
opt :help, "Display Help"
|
|
47
47
|
opt :id, "ID of the archive to authorize.", :type => :string
|
|
48
|
-
opt :key, "AWS Access Key", :type => :string
|
|
49
48
|
opt :level, "Log level [debug|info|warn|error].", :type => :string,
|
|
50
49
|
:default => 'info'
|
|
51
|
-
opt :secret, "AWS Secret Access Key", :type => :string
|
|
52
50
|
opt :name, "Name of archive.", :type => :string
|
|
51
|
+
opt :aws_access_key, "AWS Access Key ID", :type => :string,
|
|
52
|
+
:short => :none
|
|
53
|
+
opt :aws_secret_key, "AWS Secret Access Key", :type => :string,
|
|
54
|
+
:short => :none
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
|
data/lib/heirloom/cli/build.rb
CHANGED
|
@@ -27,19 +27,22 @@ module Heirloom
|
|
|
27
27
|
exit 1
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
ensure_directory :path => @opts[:directory], :config => @config
|
|
31
|
+
ensure_valid_secret :secret => @opts[:secret], :config => @config
|
|
32
|
+
|
|
30
33
|
@archive.destroy if @archive.exists?
|
|
31
34
|
|
|
32
35
|
build = @archive.build :bucket_prefix => @opts[:base_prefix],
|
|
33
36
|
:directory => @opts[:directory],
|
|
34
37
|
:exclude => @opts[:exclude],
|
|
35
|
-
:git => @opts[:git]
|
|
38
|
+
:git => @opts[:git],
|
|
39
|
+
:secret => @opts[:secret]
|
|
36
40
|
|
|
37
41
|
if build
|
|
38
42
|
@archive.upload :bucket_prefix => @opts[:base_prefix],
|
|
39
43
|
:regions => @opts[:region],
|
|
40
44
|
:public_readable => @opts[:public],
|
|
41
45
|
:file => build
|
|
42
|
-
@archive.cleanup
|
|
43
46
|
else
|
|
44
47
|
@logger.error "Build failed."
|
|
45
48
|
exit 1
|
|
@@ -57,17 +60,15 @@ Build and upload a new archive.
|
|
|
57
60
|
|
|
58
61
|
Usage:
|
|
59
62
|
|
|
60
|
-
heirloom build -n NAME -i ID -b BASE_PREFIX -r REGION1 -r REGION2
|
|
63
|
+
heirloom build -n NAME -i ID -b BASE_PREFIX -r REGION1 -r REGION2 -d DIRECTORY_TO_BUILD
|
|
61
64
|
|
|
62
65
|
EOS
|
|
63
66
|
opt :base_prefix, "Base bucket prefix which will be combined with region. \
|
|
64
|
-
For example: -b 'test' -r 'us-west-1' will expect bucket 'test-us-west-1'
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
For example: -b 'test' -r 'us-west-1' will expect bucket 'test-us-west-1' \
|
|
68
|
+
to be present", :type => :string
|
|
69
|
+
opt :directory, "Source directory of build.", :type => :string
|
|
67
70
|
opt :exclude, "File(s) or directorie(s) to exclude. \
|
|
68
|
-
Can be specified multiple times.", :type => :string,
|
|
69
|
-
:multi => true
|
|
70
|
-
opt :key, "AWS Access Key ID", :type => :string
|
|
71
|
+
Can be specified multiple times.", :type => :string, :multi => true
|
|
71
72
|
opt :git, "Read git commit information from directory and set as archive attributes."
|
|
72
73
|
opt :help, "Display Help"
|
|
73
74
|
opt :id, "ID for archive (when -g specified, assumed to be GIT sha).", :type => :string
|
|
@@ -75,9 +76,13 @@ Can be specified multiple times.", :type => :string,
|
|
|
75
76
|
:default => 'info'
|
|
76
77
|
opt :name, "Name of archive.", :type => :string
|
|
77
78
|
opt :public, "Set this archive as public readable?"
|
|
78
|
-
opt :region, "Region(s) to upload archive.
|
|
79
|
-
|
|
80
|
-
opt :secret, "
|
|
79
|
+
opt :region, "Region(s) to upload archive. \
|
|
80
|
+
Can be specified multiple times.", :type => :string, :multi => true
|
|
81
|
+
opt :secret, "Encrypt the archive with given secret.", :type => :string
|
|
82
|
+
opt :aws_access_key, "AWS Access Key ID", :type => :string,
|
|
83
|
+
:short => :none
|
|
84
|
+
opt :aws_secret_key, "AWS Secret Access Key", :type => :string,
|
|
85
|
+
:short => :none
|
|
81
86
|
end
|
|
82
87
|
end
|
|
83
88
|
|
data/lib/heirloom/cli/destroy.rb
CHANGED
|
@@ -38,16 +38,18 @@ Destroy an archive.
|
|
|
38
38
|
|
|
39
39
|
Usage:
|
|
40
40
|
|
|
41
|
-
heirloom destroy -n NAME -i ID
|
|
41
|
+
heirloom destroy -n NAME -i ID
|
|
42
42
|
|
|
43
43
|
EOS
|
|
44
44
|
opt :help, "Display Help"
|
|
45
45
|
opt :id, "ID of the archive to display.", :type => :string
|
|
46
|
-
opt :key, "AWS Access Key ID", :type => :string
|
|
47
46
|
opt :level, "Log level [debug|info|warn|error].", :type => :string,
|
|
48
47
|
:default => 'info'
|
|
49
48
|
opt :name, "Name of archive.", :type => :string
|
|
50
|
-
opt :
|
|
49
|
+
opt :aws_access_key, "AWS Access Key ID", :type => :string,
|
|
50
|
+
:short => :none
|
|
51
|
+
opt :aws_secret_key, "AWS Secret Access Key", :type => :string,
|
|
52
|
+
:short => :none
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
end
|