MuranoCLI 3.0.1 → 3.0.2

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.
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