heirloom 0.5.0rc2 → 0.5.0rc3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|