MrMurano 1.5.5 → 1.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: 3ac31eaa1f880c2269de0ebf0b44af394c8c7d80
4
- data.tar.gz: b060f57b1dc7ec60242408458a4541963a7b061b
3
+ metadata.gz: d0642fae83286309c41974774d6ec3fdc7bd974d
4
+ data.tar.gz: 103ad1f76094b609f67b720fa59c2c61cbea8f38
5
5
  SHA512:
6
- metadata.gz: d711b5f10c54a489ffef3cf03584014516be2035db33b92434935ac485d53731faf95a53b20ddd648e7faf37d188b7da1f89563ef452b678ed2d48088f74bbcc
7
- data.tar.gz: 79c236e485bf9fccf3c865a0bcfdcec932a1b786830af0e5443e068dada40928415d63d7872f4f20805ccdc7fe7fbdb60b9e2f09103beefa7de7d086e7eba8c7
6
+ metadata.gz: 1ae0f3fa923702d749407014c7379e8004789d893a82f2727c9a6e72834fe200036dbbc56bb8efa8f949b08b593d021826cde1085db7d31c536591eefaf4539a
7
+ data.tar.gz: 753a5a77d087f74d4eaf8680e58d87e2dfdf0b14ecaeed2c1faa01e2053d634f3df94f2742d61f4f192f7b681764f713d4834d4ad19bb8733f484f6802d786a4
data/README.markdown CHANGED
@@ -7,7 +7,7 @@ Do more from the command line with [Murano](https://exosite.com/platform/)
7
7
 
8
8
  ## Usage
9
9
 
10
- To start from an existing project in Murano
10
+ ### To start from an existing project in Murano
11
11
  ```
12
12
  mkdir myproject
13
13
  cd myproject
@@ -18,6 +18,22 @@ mr syncdown -V
18
18
  Do stuff, see what changed: `mr status` or `mr diff`.
19
19
  Then deploy with `mr syncup`
20
20
 
21
+ ### To start a brand new project
22
+ There are a few steps and pieces to getting a solution with a product up and
23
+ running in Murano. Here is the list.
24
+
25
+ - Pick a bussiness: `mr account --business`
26
+ - Set it: `mr config business.id ZZZZZZZZZ`
27
+ - Create a product: `mr product create myawesomeproduct`
28
+ - Save the result: `mr config product.id YYYYYYYYY`
29
+ - Define the product: `mr product spec push --file prd.spec`
30
+ - Create a solution: `mr solution create myawesomesolution`
31
+ - Save the result: `mr config solution.id XXXXXX`
32
+ - Sync solution code up: `mr syncup -V`
33
+ - Assign the prodcut to the solution: `mr assign set`
34
+
35
+ Do stuff, see what changed: `mr status` or `mr diff`.
36
+ Then deploy with `mr syncup`
21
37
 
22
38
  ## Install
23
39
 
@@ -117,11 +117,33 @@ module MrMurano
117
117
  get('business/' + $cfg['business.id'] + '/product/')
118
118
  end
119
119
 
120
+ ## Create a new product in the current business
121
+ def new_product(name, type='onepModel')
122
+ raise "Missing Bussiness ID" if $cfg['business.id'].nil?
123
+ post('business/' + $cfg['business.id'] + '/product/', {:label=>name, :type=>type})
124
+ end
125
+
126
+ def delete_product(modelId)
127
+ raise "Missing Bussiness ID" if $cfg['business.id'].nil?
128
+ delete('business/' + $cfg['business.id'] + '/product/' + modelId)
129
+ end
130
+
120
131
  def solutions
121
132
  raise "Missing Bussiness ID" if $cfg['business.id'].nil?
122
133
  get('business/' + $cfg['business.id'] + '/solution/')
123
134
  end
124
135
 
136
+ ## Create a new solution
137
+ def new_solution(name, type='dataApi')
138
+ raise "Missing Bussiness ID" if $cfg['business.id'].nil?
139
+ post('business/' + $cfg['business.id'] + '/solution/', {:label=>name, :type=>type})
140
+ end
141
+
142
+ def delete_solution(apiId)
143
+ raise "Missing Bussiness ID" if $cfg['business.id'].nil?
144
+ delete('business/' + $cfg['business.id'] + '/solution/' + apiId)
145
+ end
146
+
125
147
  end
126
148
  end
127
149
 
@@ -60,8 +60,10 @@ module MrMurano
60
60
  end
61
61
  @paths << ConfigFile.new(:private, @projectDir + CFG_PRVT_NAME)
62
62
  @paths << ConfigFile.new(:project, @projectDir + CFG_FILE_NAME)
63
+ fixModes(@projectDir + CFG_DIR_NAME)
63
64
  end
64
65
  @paths << ConfigFile.new(:user, Pathname.new(Dir.home) + CFG_FILE_NAME)
66
+ fixModes(Pathname.new(Dir.home) + CFG_DIR_NAME)
65
67
  @paths << ConfigFile.new(:system, Pathname.new(CFG_SYS_NAME))
66
68
  @paths << ConfigFile.new(:defaults, nil, IniFile.new())
67
69
 
@@ -135,6 +137,14 @@ module MrMurano
135
137
  end
136
138
  private :findProjectDir
137
139
 
140
+ def fixModes(path)
141
+ if path.directory? then
142
+ path.chmod(0700)
143
+ elsif path.file? then
144
+ path.chmod(0600)
145
+ end
146
+ end
147
+
138
148
  def file_at(name, scope=:project)
139
149
  case scope
140
150
  when :internal
@@ -8,9 +8,15 @@ require 'MrMurano/commands/domain'
8
8
  require 'MrMurano/commands/exportImport'
9
9
  require 'MrMurano/commands/keystore'
10
10
  require 'MrMurano/commands/logs'
11
- require 'MrMurano/commands/productEnable'
11
+ require 'MrMurano/commands/productCreate'
12
+ require 'MrMurano/commands/productDelete'
13
+ require 'MrMurano/commands/productList'
12
14
  require 'MrMurano/commands/productSpec'
13
15
  require 'MrMurano/commands/productWrite'
16
+ require 'MrMurano/commands/serialNumberCmds'
17
+ require 'MrMurano/commands/solutionCreate'
18
+ require 'MrMurano/commands/solutionDelete'
19
+ require 'MrMurano/commands/solutionList'
14
20
  require 'MrMurano/commands/status'
15
21
  require 'MrMurano/commands/sync'
16
22
  require 'MrMurano/commands/timeseries'
@@ -0,0 +1,26 @@
1
+
2
+ command 'product create' do |c|
3
+ c.syntax = %{mr product create <name>}
4
+ c.description = %{Create a new product}
5
+
6
+ c.action do |args, options|
7
+ if args.count < 1 then
8
+ say_error "Name of product missing"
9
+ return
10
+ end
11
+ name = args[0]
12
+
13
+ acc = MrMurano::Account.new
14
+ ret = acc.new_product(name)
15
+ if not ret.kind_of?(Hash) and not ret.empty? then
16
+ say_error "Create failed: #{ret.to_s}"
17
+ return
18
+ end
19
+
20
+ # create doesn't return anything, so we need to go look for it.
21
+ ret = acc.products.select{|i| i[:label] == name}
22
+ say ret.first[:modelId]
23
+
24
+ end
25
+ end
26
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,35 @@
1
+ require 'MrMurano/Account'
2
+
3
+ command 'product delete' do |c|
4
+ c.syntax = %{mr product delete <product>}
5
+ c.summary = %{Delete a product}
6
+ c.description = %{Delete a product}
7
+
8
+ c.action do |args, options|
9
+ if args.count < 1 then
10
+ say_error "Product id or name missing"
11
+ return
12
+ end
13
+ name = args[0]
14
+
15
+ acc = MrMurano::Account.new
16
+
17
+ # Need to convert what we got into the internal PID.
18
+ ret = acc.products.select{|i| i.has_value? name }
19
+
20
+ if $cfg['tool.debug'] then
21
+ say "Matches found:"
22
+ pp ret
23
+ end
24
+
25
+ if ret.empty? then
26
+ say_error "No product matching '#{name}' found. Nothing to delete."
27
+ else
28
+ ret = acc.delete_product(ret.first[:pid])
29
+ if not ret.kind_of?(Hash) and not ret.empty? then
30
+ say_error "Delete failed: #{ret.to_s}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,23 @@
1
+ require 'MrMurano/Account'
2
+ require 'terminal-table'
3
+
4
+ command 'product list' do |c|
5
+ c.syntax = %{mr product list [options]}
6
+ c.description = %{List products}
7
+ c.option '--idonly', 'Only return the ids'
8
+
9
+ c.action do |args, options|
10
+ acc = MrMurano::Account.new
11
+ data = acc.products
12
+ if options.idonly then
13
+ say data.map{|row| row[:pid]}.join(' ')
14
+ else
15
+ busy = data.map{|r| [r[:label], r[:type], r[:pid], r[:modelId]]}
16
+ table = Terminal::Table.new :rows => busy, :headings => ['Label', 'Type', 'PID', 'ModelID']
17
+ say table
18
+ end
19
+ end
20
+ end
21
+ alias_command :product, 'product list'
22
+
23
+ # vim: set ai et sw=2 ts=2 :
@@ -37,8 +37,8 @@ command 'product spec convert' do |c|
37
37
  end
38
38
  end
39
39
 
40
- command 'product spec' do |c|
41
- c.syntax = %{mr product spec [--file FILE]}
40
+ command 'product spec push' do |c|
41
+ c.syntax = %{mr product spec push [--file FILE]}
42
42
  c.summary = %{Upload a new specification for a product}
43
43
 
44
44
  c.option '--file FILE', "The spec file to upload"
@@ -89,6 +89,7 @@ command 'product spec pull' do |c|
89
89
  puts spec.to_yaml
90
90
  end
91
91
  end
92
-
93
92
  end
93
+ alias_command 'product spec', 'product spec pull'
94
+
94
95
  # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,75 @@
1
+ require 'MrMurano/Product'
2
+ require 'terminal-table'
3
+
4
+ command 'sn list' do |c|
5
+ c.syntax = %{mr sn list [options]}
6
+ c.summary = %{List serial numbers for a product}
7
+
8
+ c.option '--offset NUMBER', Integer, %{Offset to start listing at}
9
+ c.option '--limit NUMBER', Integer, %{How many devices to return}
10
+
11
+ c.action do |args,options|
12
+ options.default :offset=>0, :limit=>50
13
+
14
+ prd = MrMurano::Product.new
15
+ data = prd.list(options.offset, options.limit)
16
+ busy = data.map{|row| [row[:sn], row[:status], row[:rid]]}
17
+ table = Terminal::Table.new :rows => busy, :headings => ['SN', 'Status', 'RID']
18
+ say table
19
+ end
20
+ end
21
+ alias_command :sn, 'sn list'
22
+
23
+ command 'sn enable' do |c|
24
+ c.syntax = %{mr sn enable [<sn>|--file <sns>]}
25
+ c.summary = %{Enable a serial number; Creates device in Murano}
26
+ c.description = %{Enables serial numbers, creating the digial shadow in Murano.
27
+
28
+ NOTE: This opens the 24 hour activation window. If the device does not make
29
+ the activation call within this time, it will need to be enabled again.
30
+ }
31
+ c.option '-f', '--file FILE', %{A file of serial numbers, one per line}
32
+
33
+ c.action do |args,options|
34
+ prd = MrMurano::Product.new
35
+ if options.file then
36
+ File.open(options.file) do |io|
37
+ io.each_line do |line|
38
+ line.strip!
39
+ prd.enable(line) unless line.empty?
40
+ end
41
+ end
42
+ elsif args.count > 0 then
43
+ prd.enable(args[0])
44
+ else
45
+ say_error "Missing a serial number to enable"
46
+ end
47
+ end
48
+ end
49
+
50
+ command 'sn activate' do |c|
51
+ c.syntax = %{mr sn activate <sn>}
52
+ c.summary = %{Activate a serial number, retriving its CIK}
53
+ c.description = %{Activates a serial number.
54
+
55
+ Generally you should not use this. Instead the device should make the activation
56
+ call itself and save the CIK token. Its just that sometimes when building a
57
+ proof-of-concept it is just easier to hardcode the CIK.
58
+
59
+ Note that you can only activate a device once. After that you cannot retrive the
60
+ CIK again.
61
+ }
62
+
63
+ c.action do |args,options|
64
+ if args.count < 1 then
65
+ say_error "Serial number missing"
66
+ return
67
+ end
68
+ sn = args.first
69
+
70
+ prd = MrMurano::ProductSerialNumber.new
71
+ pp prd.activate(sn)
72
+
73
+ end
74
+ end
75
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,26 @@
1
+
2
+ command 'solution create' do |c|
3
+ c.syntax = %{mr solution create <name>}
4
+ c.description = %{Create a new solution}
5
+
6
+ c.action do |args, options|
7
+ if args.count < 1 then
8
+ say_error "Name of solution missing"
9
+ return
10
+ end
11
+ name = args[0]
12
+
13
+ acc = MrMurano::Account.new
14
+ ret = acc.new_solution(name)
15
+ if not ret.kind_of?(Hash) and not ret.empty? then
16
+ say_error "Create failed: #{ret.to_s}"
17
+ return
18
+ end
19
+
20
+ # create doesn't return anything, so we need to go look for it.
21
+ ret = acc.solutions.select{|i| i[:domain] =~ /#{name}\./}
22
+ say ret.first[:apiId]
23
+
24
+ end
25
+ end
26
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,34 @@
1
+ require 'MrMurano/Account'
2
+
3
+ command 'solution delete' do |c|
4
+ c.syntax = %{mr solution delete <solution id>}
5
+ c.description = %{Delete a solution}
6
+
7
+ c.action do |args, options|
8
+ if args.count < 1 then
9
+ say_error "Solution id or name missing"
10
+ return
11
+ end
12
+ name = args[0]
13
+
14
+ acc = MrMurano::Account.new
15
+
16
+ # Need to convert what we got into the internal PID.
17
+ ret = acc.solutions.select{|i| i.has_value?(name) or i[:domain] =~ /#{name}\./ }
18
+
19
+ if $cfg['tool.debug'] then
20
+ say "Matches found:"
21
+ pp ret
22
+ end
23
+
24
+ if ret.empty? then
25
+ say_error "No solution matching '#{name}' found. Nothing to delete."
26
+ else
27
+ ret = acc.delete_solution(ret.first[:sid])
28
+ if not ret.kind_of?(Hash) and not ret.empty? then
29
+ say_error "Delete failed: #{ret.to_s}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,23 @@
1
+ require 'MrMurano/Account'
2
+ require 'terminal-table'
3
+
4
+ command 'solution list' do |c|
5
+ c.syntax = %{mr solution list [options]}
6
+ c.description = %{List solutions}
7
+ c.option '--idonly', 'Only return the ids'
8
+
9
+ c.action do |args, options|
10
+ acc = MrMurano::Account.new
11
+ data = acc.solutions
12
+ if options.idonly then
13
+ say data.map{|row| row[:apiId]}.join(' ')
14
+ else
15
+ busy = data.map{|r| [r[:apiId], r[:domain], r[:type], r[:sid]]}
16
+ table = Terminal::Table.new :rows => busy, :headings => ['API ID', 'Domain', 'Type', 'SID']
17
+ say table
18
+ end
19
+ end
20
+ end
21
+ alias_command :solution, 'solution list'
22
+
23
+ # vim: set ai et sw=2 ts=2 :
@@ -1,4 +1,4 @@
1
1
  module MrMurano
2
- VERSION = '1.5.5'.freeze
2
+ VERSION = '1.6.0'.freeze
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: MrMurano
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.5
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Conrad Tadpol Tilstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2016-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -217,9 +217,15 @@ files:
217
217
  - lib/MrMurano/commands/exportImport.rb
218
218
  - lib/MrMurano/commands/keystore.rb
219
219
  - lib/MrMurano/commands/logs.rb
220
- - lib/MrMurano/commands/productEnable.rb
220
+ - lib/MrMurano/commands/productCreate.rb
221
+ - lib/MrMurano/commands/productDelete.rb
222
+ - lib/MrMurano/commands/productList.rb
221
223
  - lib/MrMurano/commands/productSpec.rb
222
224
  - lib/MrMurano/commands/productWrite.rb
225
+ - lib/MrMurano/commands/serialNumberCmds.rb
226
+ - lib/MrMurano/commands/solutionCreate.rb
227
+ - lib/MrMurano/commands/solutionDelete.rb
228
+ - lib/MrMurano/commands/solutionList.rb
223
229
  - lib/MrMurano/commands/status.rb
224
230
  - lib/MrMurano/commands/sync.rb
225
231
  - lib/MrMurano/commands/timeseries.rb
@@ -1,30 +0,0 @@
1
- require 'MrMurano/Product'
2
-
3
- command 'product enable' do |c|
4
- c.syntax = %{mr product enable [<sn>|--file <sns>]}
5
- c.summary = %{Enable a serial number; Creates device in Murano}
6
- c.description = %{Enables serial numbers, creating the digial shadow in Murano.
7
-
8
- NOTE: This opens the 24 hour activation window. If the device does not make
9
- the activation call within this time, it will need to be enabled again.
10
- }
11
- c.option '-f', '--file FILE', %{A file of serial numbers, one per line}
12
-
13
- c.action do |args,options|
14
- prd = MrMurano::Product.new
15
- if options.file then
16
- File.open(options.file) do |io|
17
- io.each_line do |line|
18
- line.strip!
19
- prd.enable(line) unless line.empty?
20
- end
21
- end
22
- elsif args.count > 0 then
23
- prd.enable(args[0])
24
- else
25
- say_error "Missing a serial number to enable"
26
- end
27
- end
28
- end
29
-
30
- # vim: set ai et sw=2 ts=2 :