Birst_Command 0.5.0 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6bad6616cef05fab628640a4acabc9b7c219baf4
4
- data.tar.gz: d4e2bf27651cf4ef20d1038b064ee8f7f4b83bbe
3
+ metadata.gz: a54ea884b6fdfe9bdcb8e1927c3bfa1bc48d80c0
4
+ data.tar.gz: 643fea5022b6b6f58a616462dbbf1ea053ad0e7e
5
5
  SHA512:
6
- metadata.gz: b3d0ba0d5ad7a2609aefde09576f90fe927a3caaeba804967510cfce381271878069e9524d1e72502c6b777c61a84ffa9376771ba715888a35bbe5af81372e5f
7
- data.tar.gz: fa825d4847ec8e2d6dc06b7af1992e6e3f352f030649e64135bb622f51a3d5d5e156b7d38e5fa7f104ed7daae657350ea70f1a8c3521504923042c2222f46077
6
+ metadata.gz: 79b9f9032f8d8a9acfd3782560b9bc2a3f2164dc9862f3f9cb5c53c59156fbba418306c467a55fb99a8f8b3904c4487e0e0e647cbc08f5b7811268d8594d663d
7
+ data.tar.gz: 9563a4c7d0cced6aa03c3e4351ced654d56cce4286a2f30112358ba68448dab83b944b597fbca04c214896d8b3c837bbf61806515feaa4c22e09f7c713332cca
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -1,7 +1,7 @@
1
- # -*- encoding: utf-8 -*-
1
+ # -*- encoding: utf-8 mode: ruby -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
- require 'Birst_Command/version'
4
+ require 'birst_command/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "Birst_Command"
@@ -15,9 +15,10 @@ Gem::Specification.new do |s|
15
15
  s.rubyforge_project = "Birst_Command"
16
16
 
17
17
  s.required_ruby_version = '~> 2'
18
- s.add_runtime_dependency "savon", ["~> 2.0"]
18
+ s.add_runtime_dependency "savon", ["~> 2.5"]
19
19
  s.add_runtime_dependency "httpclient", ["~> 2.3"]
20
20
  s.add_runtime_dependency "envcrypt", ["~> 0.1"]
21
+ s.add_runtime_dependency "configatron", ["~> 3.2"]
21
22
 
22
23
  s.files = `git ls-files`.split("\n")
23
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,23 @@
1
+ Changelog
2
+ ==============
3
+
4
+ ### v0.6.0
5
+ - Config file now uses YAML instead of JSON
6
+
7
+ - Replaced the `Config` module with a `Settings` constant that uses
8
+ [Configatron](https://github.com/markbates/configatron) to configure
9
+ default settings for all subsequent sessions.
10
+
11
+ - Remove the `start` method of `Birst_Command::Session`. Sessions are now
12
+ created using `new`. All arguments use `Settings` as defaults, but can
13
+ be overridden on a session-by-session basis.
14
+
15
+ - Renamed `Session#token` to `Session#login_token`.
16
+
17
+ - Renamed `Session#auth_cookies` to `Session#auth_cookie`.
18
+
19
+ - Replaced `Session` option `use_cookie` with `auth_cookie`.
20
+
21
+
22
+ ### v0.5.0
23
+ - Migrated password handling to use Envcrypt
data/Gemfile CHANGED
@@ -1,4 +1,8 @@
1
+ # -*- mode: ruby -*-
1
2
  source 'https://rubygems.org'
2
- gem 'savon', '~> 2.0'
3
- gem 'httpclient'
4
- gem 'envcrypt', '~> 0.1'
3
+ ruby '2.0.0'
4
+
5
+ gemspec
6
+ group :development do
7
+ gem 'rspec', '~> 2.14'
8
+ end
@@ -0,0 +1,65 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ Birst_Command (0.6.0)
5
+ configatron (~> 3.2)
6
+ envcrypt (~> 0.1)
7
+ httpclient (~> 2.3)
8
+ savon (~> 2.5)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ akami (1.2.2)
14
+ gyoku (>= 0.4.0)
15
+ nokogiri
16
+ builder (3.2.2)
17
+ configatron (3.2.0)
18
+ diff-lcs (1.2.5)
19
+ envcrypt (0.1.0)
20
+ gyoku (1.1.1)
21
+ builder (>= 2.1.2)
22
+ httpclient (2.4.0)
23
+ httpi (2.1.0)
24
+ rack
25
+ rubyntlm (~> 0.3.2)
26
+ macaddr (1.7.1)
27
+ systemu (~> 2.6.2)
28
+ mime-types (1.25.1)
29
+ mini_portile (0.6.0)
30
+ nokogiri (1.6.2.1)
31
+ mini_portile (= 0.6.0)
32
+ nori (2.4.0)
33
+ rack (1.5.2)
34
+ rspec (2.99.0)
35
+ rspec-core (~> 2.99.0)
36
+ rspec-expectations (~> 2.99.0)
37
+ rspec-mocks (~> 2.99.0)
38
+ rspec-core (2.99.0)
39
+ rspec-expectations (2.99.0)
40
+ diff-lcs (>= 1.1.3, < 2.0)
41
+ rspec-mocks (2.99.0)
42
+ rubyntlm (0.3.4)
43
+ savon (2.5.1)
44
+ akami (~> 1.2.0)
45
+ builder (>= 2.1.2)
46
+ gyoku (~> 1.1.0)
47
+ httpi (~> 2.1.0)
48
+ nokogiri (>= 1.4.0)
49
+ nori (~> 2.4.0)
50
+ uuid (~> 2.3.7)
51
+ wasabi (~> 3.3.0)
52
+ systemu (2.6.4)
53
+ uuid (2.3.7)
54
+ macaddr (~> 1.0)
55
+ wasabi (3.3.0)
56
+ httpi (~> 2.0)
57
+ mime-types (< 2.0.0)
58
+ nokogiri (>= 1.4.0)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ Birst_Command!
65
+ rspec (~> 2.14)
data/README.md CHANGED
@@ -11,8 +11,8 @@ Birst user that needed to set up a very basic Ruby interface.
11
11
 
12
12
  # Installation & Setup
13
13
 
14
- **SPECIAL NOTE:** Password management has changed since version 0.4.0.
15
- Read below for details.
14
+ **SPECIAL NOTE:** Many changes since version 0.5.0. Read the
15
+ [Changelog](CHANGELOG.md).
16
16
 
17
17
  Prerequisites: Ruby > 2.0 and rubygems.
18
18
 
@@ -21,15 +21,18 @@ rbenv/bundler as you prefer.
21
21
 
22
22
  After installing, you'll need to create a Birst Command config file
23
23
  that contains the credentials you'll use to connect to Birst. This
24
- config file should look like,
25
-
26
- {
27
- "wsdl": "https://app2102.bws.birst.com/CommandWebService.asmx?WSDL",
28
- "endpoint": "https://app2102.bws.birst.com/CommandWebService.asmx",
29
- "username": "name@myplace.com",
30
- "password": "encrypted pwd"
31
- }
32
-
24
+ is a yaml file that should look something like
25
+
26
+ ````yaml
27
+ ---
28
+ session:
29
+ wsdl: "https://app2101.bws.birst.com/CommandWebService.asmx?WSDL"
30
+ endpoint: "https://app2101.bws.birst.com/CommandWebService.asmx"
31
+ username: "BirstUsername"
32
+ password: "EncryptedPassword"
33
+ soap_log: true
34
+ soap_log_level: :debug
35
+ ````
33
36
  Save it to `$HOME/.birstcl`. Most users should only need to modify
34
37
  the username and password. (**Note**: do not use `login.bws.birst.com`
35
38
  since it does not use an updated WSDL; a specific app server must be
@@ -56,6 +59,15 @@ Copy and paste the encrypted password (aka "secret') into the
56
59
  running in a development environment, you can include these in your
57
60
  bash `~/.profile` file.
58
61
 
62
+ Also note that the YAML config file is pre-processed with ERB. So if
63
+ you also want to keep your encrypted password in an environment
64
+ variable, you could replace the `password` line above with
65
+ ````yaml
66
+ ...
67
+ password: "<%= ENV['MY_ENCRYPTED_PASSWORD'] %>"
68
+ ...
69
+ ````
70
+
59
71
  # Usage - Birst command line tool
60
72
 
61
73
  Birst Command also installs a rudimentary command line tool for interacting
@@ -106,9 +118,13 @@ In your Ruby program, include the Birst Command gem and load the config file via
106
118
  ````ruby
107
119
  require 'rubygems'
108
120
  require 'bundler/setup'
109
- require 'Birst_Command'
121
+ require 'birst_command'
122
+
123
+ Birst_Command.load_settings_from_file(file)
124
+
125
+ # Or you can forego the settings file and set them explicitly in code via
126
+ Birst_Command::Settings.session.username = "George"
110
127
 
111
- Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"config.json"))
112
128
  ````
113
129
 
114
130
  Birst commands are submitted in session blocks, which automatically
@@ -117,7 +133,7 @@ logging out. For example, to list all spaces that you have rights to,
117
133
  you can submit the following code
118
134
 
119
135
  ````ruby
120
- Birst_Command::Session.start do |bc|
136
+ Birst_Command::Session.new do |bc|
121
137
  spaces = bc.list_spaces
122
138
  puts "#{JSON.pretty_generate spaces}"
123
139
  end
@@ -153,7 +169,7 @@ as an argument hash. All arguments are mandatory even if they're blank/null
153
169
  (Birst web API requirement). For example, to create a new space,
154
170
 
155
171
  ````ruby
156
- Birst_Command::Session.start do |bc|
172
+ Birst_Command::Session.new do |bc|
157
173
  new_space_id = bc.create_new_space :spaceName => "myNewSpace", :comments => "Just testing",:automatic => "false"
158
174
  end
159
175
  ````
@@ -167,16 +183,16 @@ a copy job and save the `session_cookie` and `job_token` in variables.
167
183
  ````ruby
168
184
  session_cookie = nil
169
185
  job_token = nil
170
- Session.start do |bc|
186
+ Bist_Command::Session.new do |bc|
171
187
  job_token = bc.copy_space :spFromID => @from_id, :spToID => @to_id, :mode => "replicate", :options => "data;datastore;useunloadfeature"
172
- session_cookie = bc.auth_cookies
188
+ session_cookie = bc.auth_cookie
173
189
  end
174
190
  ````
175
191
  In a subsequent session we can use the `session_cookie` on login via
176
192
 
177
193
  ````ruby
178
194
  is_job_complete = false
179
- Session.start use_cookie: session_cookie do |bc|
195
+ Birst_Command::Session.new auth_cookie: session_cookie do |bc|
180
196
  is_job_complete = bc.is_job_complete :jobToken => job_token
181
197
  end
182
198
  puts "COMPLETE? #{is_job_complete}"
@@ -224,8 +240,3 @@ entirely consistent in its use of camelCase for arguments (e.g.,
224
240
  `listUsersInSpace`). This inconsistency requires us to **submit
225
241
  commands as snake_case and arguments as the camelCase that Birst
226
242
  uses.**
227
-
228
- # Changelog
229
-
230
- * 0.5.0
231
- * Migrated password handling to use Envcrypt
data/Rakefile CHANGED
@@ -1,14 +1 @@
1
1
  # -*- mode: ruby -*-
2
-
3
- require 'rake/testtask'
4
-
5
- task :default => [:test_all]
6
-
7
- # Run a specific unit test with `rake test TEST=test/Datalib/test_datalib.rb`
8
- Rake::TestTask.new do |t|
9
-
10
- t.libs << "test"
11
- t.test_files = FileList['test/*/test_*.rb']
12
- t.verbose = true
13
-
14
- end
@@ -50,13 +50,6 @@ module BirstCL
50
50
  @options[:arguments] = eval(opt)
51
51
  end
52
52
 
53
- =begin
54
- @options[:json_full_path] = nil
55
- opts.on("-f","--file <JSON FILE>","Path to JSON file containing command") do |opt|
56
- @options[:json_full_path] = opt
57
- end
58
- =end
59
-
60
53
  @options[:config_full_path] = "#{ENV['HOME']}/.birstcl"
61
54
  opts.on("-s","--config_file <CONFIG FILE>", "Path to config file containing credentials (default: $HOME/.birstcl)") do |opt|
62
55
  @options[:config_full_path] = opt
@@ -76,7 +69,7 @@ module BirstCL
76
69
 
77
70
 
78
71
  def read_config_file
79
- Birst_Command::Config.read_config(@options[:config_full_path])
72
+ Birst_Command.load_settings_from_file(@options[:config_full_path])
80
73
  end
81
74
 
82
75
  def write_cookie_file(file_full_path)
@@ -96,11 +89,11 @@ module BirstCL
96
89
 
97
90
  output[:command] = @options[:command]
98
91
  output[:arguments] = @options[:arguments]
99
- Birst_Command::Session.start use_cookie: @session_cookie do |bc|
100
- output[:token] = bc.token
101
- output[:auth_cookies] = bc.auth_cookies.inspect
92
+ Birst_Command::Session.new auth_cookie: @session_cookie do |bc|
93
+ output[:login_token] = bc.login_token
94
+ output[:auth_cookies] = bc.auth_cookie.inspect
102
95
  output[:result] = bc.send(@options[:command], @options[:arguments])
103
- @session_cookie = bc.auth_cookies
96
+ @session_cookie = bc.auth_cookie
104
97
  end
105
98
  puts "#{JSON.pretty_generate output}"
106
99
  write_cookie_file(@options[:write_cookie_full_path])
@@ -5,8 +5,10 @@ require 'base64'
5
5
  require 'securerandom'
6
6
  require 'json'
7
7
  require 'envcrypt'
8
+ require 'configatron/core'
9
+ require 'erb'
8
10
 
9
- require 'birst_command/config'
11
+ require 'birst_command/settings'
10
12
  require 'birst_command/core_additions'
11
13
  require 'birst_command/version'
12
14
  require 'birst_command/session'
@@ -6,3 +6,11 @@ class String
6
6
  gsub /^#{self[/\A\s*/]}/, ''
7
7
  end
8
8
  end
9
+
10
+ class Object
11
+ def symbolize_keys
12
+ return self.inject({}){|memo,(k,v)| memo[k.to_sym] = v.symbolize_keys; memo} if self.is_a? Hash
13
+ return self.inject([]){|memo,v | memo << v.symbolize_keys; memo} if self.is_a? Array
14
+ return self
15
+ end
16
+ end
@@ -1,74 +1,137 @@
1
1
  module Birst_Command
2
- class Session
3
- def initialize
4
- @options = Birst_Command::Config.options
5
-
6
- @client = Savon.client(
7
- wsdl: @options[:wsdl],
8
- endpoint: @options[:endpoint],
9
- convert_request_keys_to: :none,
10
- soap_version: 1,
11
- pretty_print_xml: true,
12
- filters: [:password],
13
- log_level: @options[:soap_log_level],
14
- log: @options[:soap_log]
15
- )
16
-
17
- @response = nil
18
- @token = nil
19
- @auth_cookies = nil
20
- end
21
-
22
- attr_reader :token
23
- attr_reader :auth_cookies
24
- attr_reader :response
25
2
 
3
+ # Public: Session class used to interact with Birst Web Services
4
+ class Session
26
5
 
27
- def self.start(use_cookie: nil, &b)
28
- session = self.new
29
- session.login(use_cookie: use_cookie)
30
- session.execute_block(&b)
31
- ensure
32
- session.logout
6
+ # Public: Initialize Session class
7
+ #
8
+ # wsdl - URL of soap WSDL (default: Settings.session.wsdl)
9
+ # endpoint - URL of soap endpoint (default: Settings.session.endpoint)
10
+ # soap_log - Boolean switch indicating whether logging should be performed (default: Settings.session.soap_log)
11
+ # soap_logger - Logger instance used to write log messages (default: Settings.session.soap_logger)
12
+ # soap_log_level - Logging level (default: Settings.session.soap_log_level)
13
+ # username - Username to use to login to Birst Web Services (default: Settings.session.username)
14
+ # password - Encrypted password for username (default: Settings.session.password)
15
+ # auth_cookie - Use a previously generated authorization cookie
16
+ #
17
+ # Returns nothing
18
+ def initialize(opts = {}, &block)
19
+ @login_token = nil
20
+ @options = set_options(opts)
21
+ @client = new_client
22
+
23
+ if block_given?
24
+ login_and_run(&block)
25
+ end
33
26
  end
34
27
 
28
+ attr_reader :login_token
29
+ attr_reader :auth_cookie
35
30
 
36
- def login(use_cookie: nil)
37
- crypt = Envcrypt::Envcrypter.new
38
31
 
39
- @auth_cookies = use_cookie
40
- @response = @client.call(:login,
41
- cookies: @auth_cookies,
32
+ # Public: Login to Birst using the username and password. After login,
33
+ # the auth cookie and login token are captured and stored as an instance
34
+ # variable.
35
+ #
36
+ # Returns the Savon response.
37
+ def login
38
+ response = @client.call(:login,
39
+ cookies: @auth_cookie,
42
40
  message: {
43
- username: @options[:username],
44
- password: crypt.decrypt(@options[:password])
41
+ username: @username,
42
+ password: decrypt(@password)
45
43
  })
46
44
 
47
- @auth_cookies = @response.http.cookies if @auth_cookies.nil?
48
- @token = @response.hash[:envelope][:body][:login_response][:login_result]
49
- end
50
-
51
-
52
- def execute_block(&b)
53
- yield self
45
+ @auth_cookie = response.http.cookies if @auth_cookie.nil?
46
+ @login_token = response.hash[:envelope][:body][:login_response][:login_result]
47
+ response
54
48
  end
55
49
 
56
-
50
+ # Public: Method missing used to send commands to Birst Web Services.
51
+ #
52
+ # command_name - Symbol representing the name of the Birst command (snake_case)
53
+ # *args - Optional arguments that are passed to the Birst command.
54
+ #
55
+ # Returns - The soap result as a hash
57
56
  def method_missing(command_name, *args)
58
57
  command command_name, *args
59
58
  end
60
59
 
61
-
60
+ # Public: Runs the command that is obtained from the method_missing call.
61
+ #
62
+ # command_name - Name of Birst command (snake_case).
63
+ # *args - Optional arguments that are passed to the Birst command.
64
+ #
65
+ # Returns - The soap result as a hash
62
66
  def command(command_name, *args)
63
67
  response_key = "#{command_name}_response".to_sym
64
68
  result_key = "#{command_name}_result".to_sym
65
69
 
66
70
  message = args.last.is_a?(Hash) ? args.pop : {}
67
71
  result = @client.call command_name,
68
- cookies: @auth_cookies,
69
- message: { :token => @token }.merge(message)
72
+ cookies: @auth_cookie,
73
+ message: { :token => @login_token }.merge(message)
70
74
 
71
75
  result.hash[:envelope][:body][response_key][result_key]
72
76
  end
77
+
78
+ private
79
+
80
+ # Private: Reads in an options hash and applies global default Settings
81
+ # if applicable. Options are converted into instance variables.
82
+ #
83
+ # Returns nothing.
84
+ def set_options(opts = {})
85
+ @wsdl = opts[:wsdl] || Settings.session.wsdl
86
+ @endpoint = opts[:endpoint] || Settings.session.endpoint
87
+ @soap_log = opts[:soap_log] || Settings.session.soap_log
88
+ @soap_logger = opts[:soap_logger] || Settings.session.soap_logger
89
+ @soap_log_level = opts[:soap_log_level] || Settings.session.soap_log_level
90
+ @username = opts[:username] || Settings.session.username
91
+ @password = opts[:password] || Settings.session.password
92
+ @auth_cookie = opts[:auth_cookie] || nil
93
+ end
94
+
95
+
96
+ # Private: Create a new Savon SOAP client.
97
+ #
98
+ # Returns a Savon instance configured with options specified in initialize.
99
+ def new_client
100
+ Savon.client(
101
+ wsdl: @wsdl,
102
+ endpoint: @endpoint,
103
+ convert_request_keys_to: :none,
104
+ soap_version: 1,
105
+ pretty_print_xml: true,
106
+ filters: [:password],
107
+ logger: @soap_logger,
108
+ log_level: @soap_log_level,
109
+ log: @soap_log
110
+ )
111
+ end
112
+
113
+
114
+ # Private: Login, run session commands specified in block, log out.
115
+ #
116
+ # &block - The block from the constructor is passed here and executed.
117
+ #
118
+ # Returns nothing.
119
+ def login_and_run(&block)
120
+ login
121
+ yield self
122
+ ensure
123
+ logout
124
+ end
125
+
126
+
127
+ # Private: Decrypt encrypted password (via Envcrypt).
128
+ #
129
+ # password - encrypted password.
130
+ #
131
+ # Returns decrypted password.
132
+ def decrypt(password)
133
+ crypt = Envcrypt::Envcrypter.new
134
+ crypt.decrypt(password)
135
+ end
73
136
  end
74
137
  end