bricolage 5.17.0 → 5.17.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 05fc1225db07602f098fbcd2271156076265a888
4
- data.tar.gz: 11e34d16227dfcdb02bd1d51043d99897ca0f133
3
+ metadata.gz: 4032da3e6706292157209142c6b52553b460773c
4
+ data.tar.gz: 8b629e29d61199dddb5575e5dc642f686b237fda
5
5
  SHA512:
6
- metadata.gz: 516296b703b34e4dc187f78d38d6087f01ae69867717677530ef49cf7e31e8a38ece329fc273af73891aec30d76887b1b61eda977fb26985ecb4d242aceb3fd1
7
- data.tar.gz: af04b494591374c139e1a66fce78704722ff522ee3b948c72039048d4decbd283d85710ab9da203d4a89ca4dac5b212aadb7b62f3bb986539f37cb616c3d9d78
6
+ metadata.gz: e6cb089f2d6b6f89034e17bcd26097265a75cc169e892f36b9f76cf4518da6ee5d8d584364f092fe0115781aad57157ccb98d0def50ed7a39f9a8c78e133d6d2
7
+ data.tar.gz: 4b6d42945c0151269e7e9c0f3c9f875587900db905dc54cdcab6b25bd0e7581cebdc00f601bcbc2ff3176a09266c3f33718a287e5578d55f2adb9db97ff274a0
@@ -0,0 +1,80 @@
1
+ require 'bricolage/context'
2
+ require 'forwardable'
3
+
4
+ module Bricolage
5
+ class CommandLineApplication
6
+ def CommandLineApplication.define
7
+ opts = new
8
+ yield opts
9
+ opts.parse!
10
+ opts
11
+ end
12
+
13
+ def initialize
14
+ @name = File.basename($0)
15
+ @home = nil
16
+ @env = nil
17
+ @subsys = nil
18
+ @ds = {}
19
+ @options = OptionParser.new
20
+ @options.banner = "Usage: #{@name} [options]"
21
+ define_default_options
22
+ end
23
+
24
+ attr_reader :name
25
+
26
+ def define_default_options
27
+ @options.on_tail('-e', '--environment=ENV', "Bricolage execution environment. (default: #{Context.environment})") {|env|
28
+ @env = env
29
+ }
30
+ default_home = Context.home_path
31
+ @options.on_tail('-C', '--home=PATH', "Bricolage home directory. (default: #{default_home == Dir.getwd ? '.' : default_home})") {|path|
32
+ @home = path
33
+ }
34
+ @options.on_tail('--help', 'Prints this message and quit.') {
35
+ puts @options.help
36
+ exit 0
37
+ }
38
+ end
39
+
40
+ extend Forwardable
41
+ def_delegator '@options', :on
42
+
43
+ DataSourceOpt = Struct.new(:kind, :name, :ds)
44
+
45
+ def data_source_option(long_option, description, kind:, short: nil, default: nil)
46
+ @ds[long_option] = DataSourceOpt.new(kind, default || kind)
47
+ @options.on(* [short, long_option + "=NAME", description + " (default: #{default || kind})"].compact) {|ds_name|
48
+ @ds[long_option] = DataSourceOpt.new(kind, ds_name)
49
+ }
50
+ end
51
+
52
+ def data_source(long_option)
53
+ ent = @ds[long_option] or raise ArgumentError, "no such data source entry: #{long_option}"
54
+ ent.ds ||= context.get_data_source(ent.kind, ent.name)
55
+ end
56
+
57
+ def parse!
58
+ return @options.parse!
59
+ rescue OptionParser::ParseError => err
60
+ $stderr.puts "#{$0}: error: #{err.message}"
61
+ $stderr.puts @options.help
62
+ exit 1
63
+ end
64
+
65
+ def context
66
+ @context ||= create_context
67
+ end
68
+
69
+ def create_context
70
+ Bricolage::Context.for_application(@home, @env)
71
+ end
72
+
73
+ def main
74
+ yield
75
+ rescue => ex
76
+ $stderr.puts "#{@name}: error: #{ex.message}"
77
+ exit 1
78
+ end
79
+ end
80
+ end
@@ -3,6 +3,7 @@ require 'bricolage/datasource'
3
3
  require 'bricolage/variables'
4
4
  require 'bricolage/configloader'
5
5
  require 'bricolage/logger'
6
+ require 'bricolage/exception'
6
7
  require 'forwardable'
7
8
 
8
9
  module Bricolage
@@ -10,13 +11,24 @@ module Bricolage
10
11
  class Context
11
12
  DEFAULT_ENV = 'development'
12
13
 
13
- def Context.environment(opt_env)
14
+ def Context.environment(opt_env = nil)
14
15
  opt_env || ENV['BRICOLAGE_ENV'] || DEFAULT_ENV
15
16
  end
16
17
 
17
- def Context.for_application(home_path, job_path = nil, environment: nil, global_variables: nil, logger: nil)
18
+ def Context.home_path(opt_path = nil)
19
+ FileSystem.home_path(opt_path)
20
+ end
21
+
22
+ def Context.for_application(home_path = nil, job_path_0 = nil, job_path: nil, environment: nil, global_variables: nil, logger: nil)
18
23
  env = environment(environment)
19
- fs = FileSystem.for_option_pathes(home_path, job_path, env)
24
+ if (job_path ||= job_path_0)
25
+ fs = FileSystem.for_job_path(job_path, env)
26
+ if home_path and home_path.realpath.to_s != fs.home_path.realpath.to_s
27
+ raise OptionError, "--home option and job file is exclusive"
28
+ end
29
+ else
30
+ fs = FileSystem.for_options(home_path, env)
31
+ end
20
32
  load(fs, env, global_variables: global_variables, logger: logger)
21
33
  end
22
34
 
@@ -5,24 +5,21 @@ require 'pathname'
5
5
  module Bricolage
6
6
 
7
7
  class FileSystem
8
- def FileSystem.for_option_pathes(home_path, job_path, env)
9
- if job_path
10
- home, subsys_id = extract_home_dirs(job_path)
11
- if home_path and home_path.realpath.to_s != home.realpath.to_s
12
- raise OptionError, "--home option and job file is exclusive"
13
- end
14
- new(home, env).subsystem(subsys_id)
15
- elsif home_path
16
- new(home_path, env)
17
- elsif home = ENV['BRICOLAGE_HOME']
18
- new(home, env)
19
- else
20
- new(Pathname.getwd, env)
21
- end
8
+ def FileSystem.home_path(opt_path = nil)
9
+ Pathname(opt_path || ENV['BRICOLAGE_HOME'] || Dir.getwd)
10
+ end
11
+
12
+ def FileSystem.for_options(home, env)
13
+ new(home_path(home), env)
14
+ end
15
+
16
+ def FileSystem.for_job_path(job_path, env)
17
+ home, subsys_id = parse_job_path(job_path)
18
+ new(home, env).subsystem(subsys_id)
22
19
  end
23
20
 
24
21
  # job_path -> [home_path, subsys_id]
25
- def FileSystem.extract_home_dirs(job_path)
22
+ def FileSystem.parse_job_path(job_path)
26
23
  subsys_path = Pathname(job_path).realpath.parent
27
24
  return subsys_path.parent, subsys_path.basename
28
25
  rescue SystemCallError => err
@@ -219,6 +219,11 @@ module Bricolage
219
219
  @statement.bind(*args) if @statement
220
220
  end
221
221
 
222
+ def source
223
+ "-- myexport #{@table} -> #{@s3ds.bucket_name}/#{@prefix}" +
224
+ (@statement ? "\n#{@statement.stripped_source}" : "")
225
+ end
226
+
222
227
  def s3export
223
228
  cmd = build_cmd(command_parameters)
224
229
  ds.logger.info '[CMD] ' + cmd.join(' ')
@@ -1,5 +1,6 @@
1
1
  require 'bricolage/datasource'
2
2
  require 'bricolage/commandutils'
3
+ require 'bricolage/exception'
3
4
  require 'aws-sdk'
4
5
  require 'stringio'
5
6
 
@@ -29,8 +30,8 @@ module Bricolage
29
30
  @iam_role = iam_role
30
31
  @master_symmetric_key = master_symmetric_key
31
32
  @encryption = encryption
32
- @s3cfg = s3cfg
33
- @configurations = @s3cfg ? load_configurations(@s3cfg) : nil
33
+ @s3cfg_path = s3cfg
34
+ @s3cfg = @s3cfg_path ? load_s3cfg(@s3cfg_path) : nil
34
35
  end
35
36
 
36
37
  attr_reader :endpoint
@@ -42,32 +43,42 @@ module Bricolage
42
43
  S3Task.new(self)
43
44
  end
44
45
 
45
- # For Redshift
46
+ # For Redshift COPY/UNLOAD
46
47
  def credential_string
47
48
  if @iam_role
48
49
  "aws_iam_role=#{@iam_role}"
49
- else
50
+ elsif access_key
50
51
  [
51
52
  "aws_access_key_id=#{access_key}",
52
53
  "aws_secret_access_key=#{secret_key}",
53
54
  (@master_symmetric_key && "master_symmetric_key=#{@master_symmetric_key}")
54
55
  ].compact.join(';')
56
+ else
57
+ raise ParameterError, "[s3:#{@bucket_name}] credential string requested but no credentials exist"
55
58
  end
56
59
  end
57
60
 
61
+ # AWS access key ID.
62
+ # This property may be nil, we can use EC2 instance or ECS task attached IAM role in that case.
58
63
  def access_key
59
- @access_key_id || get_config('access_key')
64
+ @access_key_id || get_s3cfg('access_key')
60
65
  end
61
66
 
67
+ # AWS secret access key.
62
68
  def secret_key
63
- @secret_access_key || get_config('secret_key')
69
+ @secret_access_key || get_s3cfg('secret_key')
64
70
  end
65
71
 
66
- def get_config(key)
67
- @configurations[key] or raise ParameterError, "missing s3cfg entry: #{key}"
72
+ # Redshift attached IAM role ARN
73
+ attr_reader :iam_role
74
+
75
+ def get_s3cfg(key)
76
+ return nil unless @s3cfg
77
+ @s3cfg[key] or raise ParameterError, "[s3:#{@bucket_name}] missing s3cfg entry: #{key}"
68
78
  end
79
+ private :get_s3cfg
69
80
 
70
- def load_configurations(path)
81
+ def load_s3cfg(path)
71
82
  h = {}
72
83
  File.foreach(path) do |line|
73
84
  case line
@@ -79,6 +90,7 @@ module Bricolage
79
90
  end
80
91
  h
81
92
  end
93
+ private :load_s3cfg
82
94
 
83
95
  attr_reader :encryption
84
96
 
@@ -1,4 +1,4 @@
1
1
  module Bricolage
2
2
  APPLICATION_NAME = 'Bricolage'
3
- VERSION = '5.17.0'
3
+ VERSION = '5.17.1'
4
4
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- bricolage (5.17.0)
4
+ bricolage (5.17.1)
5
5
  aws-sdk (~> 2)
6
6
  mysql2
7
7
  pg
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bricolage
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.17.0
4
+ version: 5.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minero Aoki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-14 00:00:00.000000000 Z
11
+ date: 2016-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -155,6 +155,7 @@ files:
155
155
  - jobclass/wait-file.rb
156
156
  - lib/bricolage.rb
157
157
  - lib/bricolage/application.rb
158
+ - lib/bricolage/commandlineapplication.rb
158
159
  - lib/bricolage/commandutils.rb
159
160
  - lib/bricolage/configloader.rb
160
161
  - lib/bricolage/context.rb