MuranoCLI 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.agignore +1 -0
  3. data/.rubocop.yml +67 -5
  4. data/Gemfile +6 -3
  5. data/MuranoCLI.gemspec +14 -10
  6. data/README.markdown +299 -126
  7. data/Rakefile +6 -1
  8. data/bin/murano +2 -2
  9. data/docs/completions/murano_completion-bash +93 -0
  10. data/lib/MrMurano.rb +19 -2
  11. data/lib/MrMurano/Business.rb +22 -19
  12. data/lib/MrMurano/Config.rb +19 -9
  13. data/lib/MrMurano/Content.rb +4 -4
  14. data/lib/MrMurano/Exchange-Element.rb +99 -0
  15. data/lib/MrMurano/Exchange.rb +137 -0
  16. data/lib/MrMurano/Gateway.rb +9 -9
  17. data/lib/MrMurano/Keystore.rb +4 -2
  18. data/lib/MrMurano/ReCommander.rb +3 -5
  19. data/lib/MrMurano/Solution-ServiceConfig.rb +12 -12
  20. data/lib/MrMurano/Solution-Services.rb +15 -14
  21. data/lib/MrMurano/Solution-Users.rb +2 -2
  22. data/lib/MrMurano/Solution.rb +43 -49
  23. data/lib/MrMurano/SolutionId.rb +28 -28
  24. data/lib/MrMurano/SyncUpDown.rb +32 -22
  25. data/lib/MrMurano/Webservice-Endpoint.rb +2 -1
  26. data/lib/MrMurano/Webservice.rb +5 -5
  27. data/lib/MrMurano/commands.rb +2 -1
  28. data/lib/MrMurano/commands/business.rb +21 -19
  29. data/lib/MrMurano/commands/domain.rb +16 -2
  30. data/lib/MrMurano/commands/exchange.rb +272 -0
  31. data/lib/MrMurano/commands/globals.rb +17 -1
  32. data/lib/MrMurano/commands/init.rb +3 -3
  33. data/lib/MrMurano/commands/link.rb +16 -16
  34. data/lib/MrMurano/commands/postgresql.rb +2 -2
  35. data/lib/MrMurano/commands/show.rb +13 -7
  36. data/lib/MrMurano/commands/solution.rb +23 -17
  37. data/lib/MrMurano/commands/solution_picker.rb +49 -44
  38. data/lib/MrMurano/commands/sync.rb +2 -1
  39. data/lib/MrMurano/commands/timeseries.rb +2 -2
  40. data/lib/MrMurano/commands/tsdb.rb +2 -2
  41. data/lib/MrMurano/hash.rb +19 -7
  42. data/lib/MrMurano/http.rb +12 -2
  43. data/lib/MrMurano/orderedhash.rb +200 -0
  44. data/lib/MrMurano/spec_commander.rb +98 -0
  45. data/lib/MrMurano/verbosing.rb +2 -2
  46. data/lib/MrMurano/version.rb +2 -2
  47. data/spec/Business_spec.rb +8 -6
  48. data/spec/Solution-ServiceConfig_spec.rb +1 -1
  49. data/spec/SyncUpDown_spec.rb +6 -6
  50. data/spec/_workspace.rb +9 -4
  51. data/spec/cmd_business_spec.rb +8 -2
  52. data/spec/cmd_common.rb +266 -25
  53. data/spec/cmd_exchange_spec.rb +118 -0
  54. data/spec/cmd_help_spec.rb +54 -13
  55. data/spec/cmd_init_spec.rb +1 -12
  56. data/spec/cmd_link_spec.rb +94 -72
  57. data/spec/spec_helper.rb +11 -16
  58. metadata +23 -17
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.16 /coding: utf-8
1
+ # Last Modified: 2017.09.07 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -13,6 +13,7 @@ def sync_add_options(c, locale)
13
13
  c.option '--[no-]delete', %(Don't delete things from #{locale})
14
14
  c.option '--[no-]create', %(Don't create things on #{locale})
15
15
  c.option '--[no-]update', %(Don't update things on #{locale})
16
+ c.option '--ignore-errors', %(Don't die on sync errors)
16
17
  end
17
18
 
18
19
  def syncdown_files(options, args=nil)
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.22 /coding: utf-8
1
+ # Last Modified: 2017.09.11 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -11,7 +11,7 @@ require 'MrMurano/Solution-ServiceConfig'
11
11
 
12
12
  module MrMurano
13
13
  class Timeseries < ServiceConfig
14
- def initialize(sid=nil)
14
+ def initialize(api_id=nil)
15
15
  # FIXME/2017-07-03: What soln types have timeseries?
16
16
  @solntype = 'application.id'
17
17
  super
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.22 /coding: utf-8
1
+ # Last Modified: 2017.09.11 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -13,7 +13,7 @@ require 'MrMurano/SubCmdGroupContext'
13
13
  module MrMurano
14
14
  module ServiceConfigs
15
15
  class Tsdb < ServiceConfig
16
- def initialize(sid=nil)
16
+ def initialize(api_id=nil)
17
17
  # FIXME/2017-07-03: What soln types have TSDBs?
18
18
  @solntype = 'application.id'
19
19
  super
@@ -1,11 +1,11 @@
1
- # Last Modified: 2017.08.20 /coding: utf-8
1
+ # Last Modified: 2017.09.07 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
5
5
  # License: MIT. See LICENSE.txt.
6
6
  # vim:tw=0:ts=2:sw=2:et:ai
7
7
 
8
- require 'orderedhash'
8
+ require 'MrMurano/orderedhash'
9
9
 
10
10
  class Hash
11
11
  # From:
@@ -73,9 +73,10 @@ def elevate_hash(hsh)
73
73
  end
74
74
  # build a hash where the default is 'false' instead of 'nil'
75
75
  Hash.new(false).merge(Hash.transform_keys_to_symbols(hsh))
76
- # 2017-08-16: Weird: [lb] seeing the Hash behave differently
77
- # after feeding through this function. Unknown keys would
78
- # return nil before, but after, return false.
76
+ # 2017-09-07: Note that after elevate_hash, the Hash returns
77
+ # false on unknown keys. This is because of the parameter to
78
+ # new: Hash.new(false). Unknown keys would return nil before,
79
+ # but after, they return false. E.g.,
79
80
  #
80
81
  # (byeebug) options
81
82
  # {:delete=>false, :create=>true, :update=>false}
@@ -89,8 +90,6 @@ def elevate_hash(hsh)
89
90
  # false
90
91
  # (byeebug) options
91
92
  # {:delete=>false, :create=>true, :update=>false, :fff=>nil}
92
- #
93
- # Work around is to test with hash.key?
94
93
  end
95
94
 
96
95
  ##
@@ -108,3 +107,16 @@ def ensure_array(item)
108
107
  end
109
108
  end
110
109
 
110
+ module HashInit
111
+ def initialize(*hash)
112
+ return unless hash.length == 1 && hash.first.is_a?(Hash)
113
+ hash.first.each do |key, val|
114
+ if respond_to? key
115
+ send("#{key}=", val)
116
+ else
117
+ $stderr.puts %(HashInit: missing hash key "#{key}")
118
+ end
119
+ end
120
+ end
121
+ end
122
+
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.20 /coding: utf-8
1
+ # Last Modified: 2017.08.24 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -84,7 +84,17 @@ module MrMurano
84
84
  if !defined?(@http) || @http.nil?
85
85
  @http = Net::HTTP.new(uri.host, uri.port)
86
86
  @http.use_ssl = true
87
- @http.start
87
+ begin
88
+ @http.start
89
+ rescue SocketError => err
90
+ # E.g., "error: Failed to open TCP connection to true:443
91
+ # (Hostname not known: true)."
92
+ error %(Net socket error: #{err.message})
93
+ exit 2
94
+ rescue StandardError => err
95
+ error %(Net request failed: #{err.message})
96
+ exit 2
97
+ end
88
98
  end
89
99
  @http
90
100
  end
@@ -0,0 +1,200 @@
1
+
2
+ # AUTHOR
3
+ # jan molic /mig/at/1984/dot/cz/
4
+ #
5
+ # DESCRIPTION
6
+ # Hash with preserved order and some array-like extensions
7
+ # Public domain.
8
+ #
9
+ # THANKS
10
+ # Andrew Johnson for his suggestions and fixes of Hash[],
11
+ # merge, to_a, inspect and shift
12
+ class OrderedHash < ::Hash
13
+ attr_accessor :order
14
+
15
+ class << self
16
+ def [] *args
17
+ hsh = OrderedHash.new
18
+ if Hash === args[0]
19
+ hsh.replace args[0]
20
+ elsif (args.size % 2) != 0
21
+ raise ArgumentError, "odd number of elements for Hash"
22
+ else
23
+ 0.step(args.size - 1, 2) do |a|
24
+ b = a + 1
25
+ hsh[args[a]] = args[b]
26
+ end
27
+ end
28
+ hsh
29
+ end
30
+ end
31
+ def initialize(*a, &b)
32
+ super
33
+ @order = []
34
+ end
35
+ def store_only a,b
36
+ store a,b
37
+ end
38
+ alias orig_store store
39
+ def store a,b
40
+ @order.push a unless has_key? a
41
+ super a,b
42
+ end
43
+ alias []= store
44
+ def == hsh2
45
+ return false if @order != hsh2.order
46
+ super hsh2
47
+ end
48
+ def clear
49
+ @order = []
50
+ super
51
+ end
52
+ def delete key
53
+ @order.delete key
54
+ super
55
+ end
56
+ def each_key
57
+ @order.each { |k| yield k }
58
+ self
59
+ end
60
+ def each_value
61
+ @order.each { |k| yield self[k] }
62
+ self
63
+ end
64
+ def each
65
+ @order.each { |k| yield k,self[k] }
66
+ self
67
+ end
68
+ alias each_pair each
69
+ def delete_if
70
+ @order.clone.each { |k|
71
+ delete k if yield(k)
72
+ }
73
+ self
74
+ end
75
+ def values
76
+ ary = []
77
+ @order.each { |k| ary.push self[k] }
78
+ ary
79
+ end
80
+ def keys
81
+ @order
82
+ end
83
+ def first
84
+ {@order.first => self[@order.first]}
85
+ end
86
+ def last
87
+ {@order.last => self[@order.last]}
88
+ end
89
+ def invert
90
+ hsh2 = Hash.new
91
+ @order.each { |k| hsh2[self[k]] = k }
92
+ hsh2
93
+ end
94
+ def reject &block
95
+ self.dup.delete_if(&block)
96
+ end
97
+ def reject! &block
98
+ hsh2 = reject(&block)
99
+ self == hsh2 ? nil : hsh2
100
+ end
101
+ def replace hsh2
102
+ @order = hsh2.keys
103
+ super hsh2
104
+ end
105
+ def shift
106
+ key = @order.first
107
+ key ? [key,delete(key)] : super
108
+ end
109
+ def unshift k,v
110
+ unless self.include? k
111
+ @order.unshift k
112
+ orig_store(k,v)
113
+ true
114
+ else
115
+ false
116
+ end
117
+ end
118
+ def push k,v
119
+ unless self.include? k
120
+ @order.push k
121
+ orig_store(k,v)
122
+ true
123
+ else
124
+ false
125
+ end
126
+ end
127
+ def pop
128
+ key = @order.last
129
+ key ? [key,delete(key)] : nil
130
+ end
131
+ def to_a
132
+ ary = []
133
+ each { |k,v| ary << [k,v] }
134
+ ary
135
+ end
136
+ def to_s
137
+ self.to_a.to_s
138
+ end
139
+ def inspect
140
+ ary = []
141
+ each {|k,v| ary << k.inspect + "=>" + v.inspect}
142
+ '{' + ary.join(", ") + '}'
143
+ end
144
+ def update hsh2
145
+ hsh2.each { |k,v| self[k] = v }
146
+ self
147
+ end
148
+ alias :merge! update
149
+ def merge hsh2
150
+ self.dup update(hsh2)
151
+ end
152
+ def select
153
+ ary = []
154
+ each { |k,v| ary << [k,v] if yield k,v }
155
+ ary
156
+ end
157
+ def class
158
+ Hash
159
+ end
160
+ def __class__
161
+ OrderedHash
162
+ end
163
+
164
+ attr_accessor "to_yaml_style"
165
+ def yaml_inline= bool
166
+ if respond_to?("to_yaml_style")
167
+ self.to_yaml_style = :inline
168
+ else
169
+ unless defined? @__yaml_inline_meth
170
+ @__yaml_inline_meth =
171
+ lambda {|opts|
172
+ YAML::quick_emit(object_id, opts) {|emitter|
173
+ emitter << '{ ' << map{|kv| kv.join ': '}.join(', ') << ' }'
174
+ }
175
+ }
176
+ class << self
177
+ def to_yaml opts = {}
178
+ begin
179
+ @__yaml_inline ? @__yaml_inline_meth[ opts ] : super
180
+ rescue
181
+ @to_yaml_style = :inline
182
+ super
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ @__yaml_inline = bool
189
+ end
190
+ def yaml_inline!() self.yaml_inline = true end
191
+
192
+ def each_with_index
193
+ @order.each_with_index { |k, index| yield k, self[k], index }
194
+ self
195
+ end
196
+ end # class OrderedHash
197
+
198
+ def OrderedHash(*a, &b)
199
+ OrderedHash.new(*a, &b)
200
+ end
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ # Last Modified: 2017.08.30 /coding: utf-8
3
+ # frozen_string_literal: true
4
+
5
+ # Copyright © 2016-2017 Exosite LLC.
6
+ # License: MIT. See LICENSE.txt.
7
+ # vim:tw=0:ts=2:sw=2:et:ai
8
+
9
+ require 'commander/import'
10
+ require 'dotenv'
11
+ require 'English'
12
+ require 'highline'
13
+ require 'pathname'
14
+ #require 'pp'
15
+ require 'rainbow'
16
+ require 'rubygems'
17
+ require 'MrMurano'
18
+ require 'MrMurano/Config'
19
+ require 'MrMurano/ProjectFile'
20
+
21
+ # DEVs: Store environs in an .env file that gets loaded here. Alternatively,
22
+ # run a Bash or similar script before you start developing.
23
+ Dotenv.load
24
+
25
+ # Don't drop traces on ^C.
26
+ # EXPLAIN/2017-06-30: [lb] not sure what "drop traces" means.
27
+ # What happens if we don't trap Ctrl-C?
28
+ # NOTE: The second parameter is either a string, or a command or block to
29
+ # call or run. Ruby honors certain special strings, like 'EXIT':
30
+ # "If the command is “EXIT”, the script will be terminated by the signal."
31
+ # Per https://ruby-doc.org/core-2.2.0/Signal.html
32
+ Signal.trap('INT', 'EXIT')
33
+
34
+ program :version, MrMurano::VERSION
35
+
36
+ program :description, %(
37
+ Manage Applications and Products in Exosite's Murano
38
+ ).strip
39
+
40
+ # If being piped, e.g.,
41
+ # murano command ... | ...
42
+ # or
43
+ # VAR=$(murano command ...)
44
+ # etc., then do not do progress.
45
+ # TEST/2017-08-23: Does this work on Windows?
46
+ ARGV.push('--no-progress') unless $stdout.tty? || ARGV.include?('--no-progress')
47
+
48
+ default_command :help
49
+
50
+ # Look for plug-ins.
51
+ pgds = [
52
+ Pathname.new(Dir.home) + '.mrmurano' + 'plugins',
53
+ Pathname.new(Dir.home) + '.murano' + 'plugins',
54
+ ]
55
+ # Add plugin dirs from configs
56
+ # This is run before the command line options are parsed, so need to check old way.
57
+ unless ARGV.include? '--skip-plugins'
58
+ pgds << Pathname.new(ENV['MR_MURANO_PLUGIN_DIR']) if ENV.key? 'MR_MURANO_PLUGIN_DIR'
59
+ pgds << Pathname.new(ENV['MURANO_PLUGIN_DIR']) if ENV.key? 'MURANO_PLUGIN_DIR'
60
+ pgds.each do |path|
61
+ next unless path.exist?
62
+ path.each_child do |plugin|
63
+ next if plugin.directory?
64
+ next unless plugin.readable?
65
+ next if plugin.basename.fnmatch('.*') # don't read anything starting with .
66
+ begin
67
+ require plugin.to_s
68
+ #rescue Exception => err
69
+ rescue StandardError => err
70
+ $stderr.puts "Failed to load plugin at #{plugin} because #{err}"
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # Look for .murano/config files.
77
+ $cfg = MrMurano::Config.new(::Commander::Runner.instance)
78
+ $cfg.load
79
+ $cfg.validate_cmd
80
+
81
+ # Look for a (legacy) Solutionfile.json.
82
+ $project = MrMurano::ProjectFile.new
83
+ $project.load
84
+
85
+ # The Commander defaults to paged help.
86
+ # The user can disable with --no-page, e.g.,
87
+ # alias murano='murano --no-page'
88
+ # We define this here and not in globals.rb because
89
+ # `murano --help` does not cause globals.rb to be sourced.
90
+ paging = nil
91
+ paging = true if ARGV.include?('--page')
92
+ paging = false if ARGV.include?('--no-page')
93
+ unless paging.nil?
94
+ program :help_paging, paging
95
+ $cfg['tool.no-page'] = !paging
96
+ end
97
+ # else, commander defaults to paging.
98
+
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.23 /coding: utf-8
1
+ # Last Modified: 2017.08.28 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -104,7 +104,7 @@ module MrMurano
104
104
 
105
105
  ## Format and print the object
106
106
  # Handles many of the raw 'unpolished' formats.
107
- def outf(obj, ios=nil, &_block)
107
+ def outf(obj, ios=nil)
108
108
  fmt = $cfg['tool.outformat']
109
109
  ios = $stdout if ios.nil?
110
110
  case fmt
@@ -1,4 +1,4 @@
1
- # Last Modified: 2017.08.23 /coding: utf-8
1
+ # Last Modified: 2017.08.31 /coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Copyright © 2016-2017 Exosite LLC.
@@ -26,7 +26,7 @@ module MrMurano
26
26
  # '3.0.0-beta.2' is changed to '3.0.0.pre.beta.2'
27
27
  # which breaks our build (which expects the version to match herein).
28
28
  # So stick to using the '.pre.X' syntax, which ruby/gems knows.
29
- VERSION = '3.0.1'
29
+ VERSION = '3.0.2'
30
30
  EXE_NAME = File.basename($PROGRAM_NAME)
31
31
  SIGN_UP_URL = 'https://exosite.com/signup/'
32
32
  end