MrMurano 1.11.3 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/README.markdown +12 -14
- data/Rakefile +2 -2
- data/TODO.taskpaper +8 -6
- data/docs/demo.md +109 -0
- data/lib/MrMurano/Account.rb +6 -3
- data/lib/MrMurano/Config.rb +13 -37
- data/lib/MrMurano/Product-1P-Device.rb +2 -0
- data/lib/MrMurano/Product-Resources.rb +5 -4
- data/lib/MrMurano/Product.rb +3 -3
- data/lib/MrMurano/Solution-File.rb +1 -2
- data/lib/MrMurano/Solution-ServiceConfig.rb +11 -1
- data/lib/MrMurano/Solution-Services.rb +24 -7
- data/lib/MrMurano/Solution-Users.rb +6 -4
- data/lib/MrMurano/SyncUpDown.rb +67 -28
- data/lib/MrMurano/commands/config.rb +4 -1
- data/lib/MrMurano/commands/exportImport.rb +3 -0
- data/lib/MrMurano/hash.rb +2 -0
- data/lib/MrMurano/http.rb +3 -3
- data/lib/MrMurano/verbosing.rb +9 -3
- data/lib/MrMurano/version.rb +1 -1
- data/spec/Account_spec.rb +104 -0
- data/spec/Config_spec.rb +202 -57
- data/spec/Http_spec.rb +204 -0
- data/spec/MakePretties_spec.rb +35 -0
- data/spec/Mock_spec.rb +13 -20
- data/spec/ProductBase_spec.rb +2 -0
- data/spec/ProductContent_spec.rb +77 -12
- data/spec/ProductResources_spec.rb +235 -0
- data/spec/Product_1P_Device_spec.rb +62 -0
- data/spec/Product_1P_RPC_spec.rb +2 -0
- data/spec/Product_spec.rb +18 -8
- data/spec/Solution-Cors_spec.rb +28 -1
- data/spec/Solution-Endpoint_spec.rb +250 -33
- data/spec/Solution-File_spec.rb +210 -0
- data/spec/Solution-ServiceConfig_spec.rb +2 -0
- data/spec/Solution-ServiceDevice_spec.rb +174 -0
- data/spec/Solution-ServiceEventHandler_spec.rb +134 -1
- data/spec/Solution-ServiceModules_spec.rb +317 -64
- data/spec/Solution-UsersRoles_spec.rb +207 -0
- data/spec/Solution_spec.rb +90 -0
- data/spec/SyncRoot_spec.rb +52 -46
- data/spec/SyncUpDown_spec.rb +364 -0
- data/spec/Verbosing_spec.rb +279 -0
- data/spec/_workspace.rb +27 -0
- data/spec/fixtures/dumped_config +47 -0
- data/spec/fixtures/product_spec_files/lightbulb-no-state.yaml +11 -0
- data/spec/fixtures/product_spec_files/lightbulb.yaml +2 -0
- data/spec/fixtures/roles-three.yaml +11 -0
- data/spec/spec_helper.rb +9 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5435dfba3b558c2de067fc23c0f3dddce44b826f
|
4
|
+
data.tar.gz: 5472c934c6ab6920ea86a5a774f1790e04028d59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18b2a24e1703142195cdb729d58136e8a49bd1237ec209e272b7345d58e4d70001e14807b39b498f59f98b6fa9e159b5f76dc4ccc647aa223484351ecad26c0a
|
7
|
+
data.tar.gz: 7e754ef2e1b9de17d40f74837bc518da249ec65bdd29e63c041edf1da16fce9a26ccb9d27aa8e45b71c84e8d01332b8164fa044da523213b9045bb8e87d95cb6
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/MrMurano.svg)](https://badge.fury.io/rb/MrMurano)
|
4
4
|
[![Build Status](https://travis-ci.org/tadpol/MrMurano.svg?branch=master)](https://travis-ci.org/tadpol/MrMurano)
|
5
|
+
[![Inline docs](http://inch-ci.org/github/exosite/MrMurano.svg?branch=master)](http://inch-ci.org/github/exosite/MrMurano)
|
5
6
|
|
6
7
|
Do more from the command line with [Murano](https://exosite.com/platform/)
|
7
8
|
|
@@ -64,6 +65,16 @@ Your `PATH` may need to be updated to find the installed `mr` command. See the
|
|
64
65
|
[Ruby Gem FAQ](http://guides.rubygems.org/faqs/#user-install). In short, you need
|
65
66
|
to add the output of `ruby -rubygems -e 'puts Gem.user_dir'` to your `PATH`.
|
66
67
|
|
68
|
+
### Windows Install
|
69
|
+
|
70
|
+
The MrMurano gem will install on Windows. There is also a single Windows binary
|
71
|
+
Setup installer availible in [releases](https://github.com/exosite/MrMurano/releases)
|
72
|
+
|
73
|
+
You can install Ruby on Windows with [RubyInstaller](http://rubyinstaller.org).
|
74
|
+
You might run into a [known SSL cert issue](http://guides.rubygems.org/ssl-certificate-update/).
|
75
|
+
If so follow the steps there to update the certs.
|
76
|
+
|
77
|
+
|
67
78
|
## Features
|
68
79
|
|
69
80
|
### Logs
|
@@ -105,7 +116,7 @@ cat >> .mrmurano.prod <<EOF
|
|
105
116
|
id=CCCCCCCC
|
106
117
|
EOF
|
107
118
|
|
108
|
-
cat
|
119
|
+
cat > .env <<EOF
|
109
120
|
MR_CONFIGFILE=.mrmurano.dev
|
110
121
|
EOF
|
111
122
|
```
|
@@ -156,10 +167,6 @@ following commands:
|
|
156
167
|
|
157
168
|
Call them with `--help` for details.
|
158
169
|
|
159
|
-
### ZSH tab completion
|
160
|
-
|
161
|
-
Basic completion support for zsh.
|
162
|
-
|
163
170
|
### Sub-directories
|
164
171
|
|
165
172
|
For the endpoints, modules, and eventhandlers directories. The can contain both
|
@@ -214,12 +221,3 @@ MrMurano also uses [bundler](http://bundler.io).
|
|
214
221
|
|
215
222
|
When submitting pull requests, please do them against the develop branch.
|
216
223
|
|
217
|
-
## Windows
|
218
|
-
|
219
|
-
The MrMurano gem will install on Windows.
|
220
|
-
|
221
|
-
You can install Ruby on Windows with [RubyInstaller](http://rubyinstaller.org).
|
222
|
-
You might run into a [known SSL cert issue](http://guides.rubygems.org/ssl-certificate-update/).
|
223
|
-
If so follow the steps there to update the certs.
|
224
|
-
|
225
|
-
|
data/Rakefile
CHANGED
@@ -46,14 +46,14 @@ task :gemit do
|
|
46
46
|
sh %{git checkout v#{mrt}}
|
47
47
|
Rake::Task[:build].invoke
|
48
48
|
Rake::Task[:bob].invoke
|
49
|
-
Rake::Task['push
|
49
|
+
Rake::Task['push:gem'].invoke
|
50
50
|
sh %{git checkout develop}
|
51
51
|
end
|
52
52
|
|
53
53
|
namespace :push do
|
54
54
|
desc 'Push gem up to RubyGems'
|
55
55
|
task :gem do
|
56
|
-
sh %{gem push
|
56
|
+
sh %{gem push #{builtGem}}
|
57
57
|
end
|
58
58
|
|
59
59
|
namespace :github do
|
data/TODO.taskpaper
CHANGED
@@ -28,8 +28,8 @@ Endpoints:
|
|
28
28
|
- Add directory support like in modules @done(2016-07-26)
|
29
29
|
|
30
30
|
Files:
|
31
|
-
- Add ignore patterns to config @done(2016-12-20)
|
32
31
|
- Switch to mime-types v3 @pri(low)
|
32
|
+
- Add ignore patterns to config @done(2016-12-20)
|
33
33
|
- Figure out how to make the hexed-sha checksum faster. @done(2016-09-23)
|
34
34
|
- Fix upload. @done(2016-08-01)
|
35
35
|
- Files won't update, they always delete then add. @done(2016-07-28)
|
@@ -56,7 +56,8 @@ Timeseries:
|
|
56
56
|
|
57
57
|
Product:
|
58
58
|
- Add option for progress bar when uploading content files.
|
59
|
-
- Support multiple products.
|
59
|
+
- Support multiple products. @done(2017-01-05)
|
60
|
+
Won't do. Future will be one-to-one.
|
60
61
|
Think about how this would work. There is the syncing of the resoruces, and then
|
61
62
|
some of the commands that use product.id.
|
62
63
|
- Auto convert exoline spec files into murano spec files on upload? @done(2016-10-27)
|
@@ -68,8 +69,6 @@ Service Device:
|
|
68
69
|
- When listing and business.id is missing, gracefully fall back to --idonly @done(2016-09-12)
|
69
70
|
|
70
71
|
Config:
|
71
|
-
- Add config tool.default_sync to set which things sync{up,down} by default
|
72
|
-
It is internally hardcoded to be -s, -a, -m, -e right now.
|
73
72
|
- Store passwords in system Keychain on system that have a Keychain.
|
74
73
|
mac OS does, various Linux desktops have a couple differnet ones. Not sure about
|
75
74
|
Windows.
|
@@ -80,6 +79,8 @@ Config:
|
|
80
79
|
|
81
80
|
Plus things like 1Password, LastPass, KeePass, and others.
|
82
81
|
|
82
|
+
- Add config sync.bydefault to set which things sync{up,down} by default @done(2017-01-05)
|
83
|
+
It is internally hardcoded to be -s, -a, -m, -e right now.
|
83
84
|
- Add ENV['MR_CONFIGFILE'] path to file to load like --configfile @done(2016-09-22)
|
84
85
|
- Maybe add dotenv support. @done(2016-09-22)
|
85
86
|
- Think about adding dev,staging,prod system; how would that work? @done(2016-09-16)
|
@@ -88,6 +89,7 @@ SyncUpDown:
|
|
88
89
|
- Document the hash keys for an item. @pri(high)
|
89
90
|
Also consider turning that hash into a Struct
|
90
91
|
- Allow specifying local files to limit actions to.
|
92
|
+
This is one the command line. The idea being to sync just one file.
|
91
93
|
|
92
94
|
SolutionBase:
|
93
95
|
- All network traffic is serialized. Make some parallel.
|
@@ -98,8 +100,8 @@ SolutionBase:
|
|
98
100
|
- Rebuild how local names and paths are computed from remote items. @done(2016-07-27)
|
99
101
|
|
100
102
|
Windows:
|
101
|
-
- Need to test with http://rubyinstaller.org on Windows. @pri(high)
|
102
|
-
- Look into http://ocra.rubyforge.org for building an exec. @pri(high)
|
103
|
+
- Need to test with http://rubyinstaller.org on Windows. @pri(high) @done(2016-12-21)
|
104
|
+
- Look into http://ocra.rubyforge.org for building an exec. @pri(high) @done(2016-12-21)
|
103
105
|
|
104
106
|
Bundles:
|
105
107
|
- Revisit this idea. Its complexity may not be worth its value.
|
data/docs/demo.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
# Every sub-command will --help
|
4
|
+
|
5
|
+
# Start anew
|
6
|
+
- Clone project: `git clone https://github.com/tadpol/GWE-Multitool.git demo01`
|
7
|
+
- `cd demo01`
|
8
|
+
|
9
|
+
- Pick a bussiness: `mr business list`
|
10
|
+
- Set it: `mr config business.id ZZZZZZZZZ`
|
11
|
+
|
12
|
+
- Create a product: `mr product create myawesomeproduct`
|
13
|
+
- Save the result: `mr config product.id YYYYYYYYY`
|
14
|
+
|
15
|
+
- Set the product definition: `mr config product.spec gwe-multitool.yaml`
|
16
|
+
- Set the directory to look for specs. `mr config location.specs spec`
|
17
|
+
- Sync the product definition up: `mr syncup -V --specs`
|
18
|
+
|
19
|
+
- Create a solution: `mr solution create myawesomesolution`
|
20
|
+
- Save the result: `mr config solution.id XXXXXX`
|
21
|
+
- Assign the product to the solution: `mr assign set`
|
22
|
+
|
23
|
+
# What got configured?
|
24
|
+
`mr config --dump`
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
# <voice type='orc'>Work Work</voice>
|
32
|
+
|
33
|
+
- What is going to change? `mr status`
|
34
|
+
- Sync solution code up: `mr syncup -V`
|
35
|
+
|
36
|
+
- Change a file
|
37
|
+
- What is going to change? `mr status`
|
38
|
+
- Details of change: `mr diff`
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
# Devices
|
44
|
+
- Add a real device: `mr product device enable 42:42:42:42:42:42`
|
45
|
+
- !!!cheet and activate by hand: `mr product device activate 42:42:42:42:42:42`
|
46
|
+
- Which resources are there? `mr product spec pull`
|
47
|
+
- What did the device write to that one resource?
|
48
|
+
`mr product device read 42:42:42:42:42:42 update_interval`
|
49
|
+
- `mr product device write 42:42:42:42:42:42 update_interval 300`
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
# Multiple configs
|
54
|
+
Because Developing, Staging, Production.
|
55
|
+
|
56
|
+
Set addition config file to load with `MR_CONFIGFILE`
|
57
|
+
|
58
|
+
Also supports '.env'
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
# Device Content Area
|
64
|
+
|
65
|
+
See GWE.
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
# Debugging
|
72
|
+
|
73
|
+
## Logs
|
74
|
+
- `mr logs`
|
75
|
+
- `mr logs --follow`
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
## Keystore
|
83
|
+
### What is in the Keystore?
|
84
|
+
`mr keystore list`
|
85
|
+
|
86
|
+
### Write and Read a Key
|
87
|
+
- `mr keystore set test greebled`
|
88
|
+
- `mr keystore get test`
|
89
|
+
|
90
|
+
### Write to a Set
|
91
|
+
- `mr keystore command sadd myset greebled`
|
92
|
+
Or any other supported Redis command.
|
93
|
+
|
94
|
+
### Remove just the ones with 'socketmap'
|
95
|
+
`mr keystore list | grep socketmap | xargs -L1 mr keystore delete`
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
## TSDB
|
101
|
+
|
102
|
+
- `mr tsdb list metrics`
|
103
|
+
- `mr tsdb list tags`
|
104
|
+
- `mr tsdb query @sn=1 temp0`
|
105
|
+
- `mr tsdb query @sn=1 temp0 --limit=4`
|
106
|
+
- `mr tsdb query @sn=1 --limit=10 -c outformat=csv --epoch ms`
|
107
|
+
|
108
|
+
|
109
|
+
|
data/lib/MrMurano/Account.rb
CHANGED
@@ -65,7 +65,7 @@ module MrMurano
|
|
65
65
|
host = $cfg['net.host']
|
66
66
|
user = $cfg['user.name']
|
67
67
|
if user.nil? then
|
68
|
-
|
68
|
+
error("No Murano user account found; please login")
|
69
69
|
user = ask("User name: ")
|
70
70
|
$cfg.set('user.name', user, :user)
|
71
71
|
end
|
@@ -74,7 +74,7 @@ module MrMurano
|
|
74
74
|
pf.load
|
75
75
|
pws = pf.get(host, user)
|
76
76
|
if pws.nil? then
|
77
|
-
|
77
|
+
error("Couldn't find password for #{user}")
|
78
78
|
pws = ask("Password: ") { |q| q.echo = "*" }
|
79
79
|
pf.set(host, user, pws)
|
80
80
|
pf.save
|
@@ -108,12 +108,15 @@ module MrMurano
|
|
108
108
|
showHttpError(request, response)
|
109
109
|
error "Check to see if username and password are correct."
|
110
110
|
@@token = nil
|
111
|
-
raise response
|
112
111
|
end
|
113
112
|
end
|
114
113
|
@@token
|
115
114
|
end
|
116
115
|
|
116
|
+
def token_reset(value=nil)
|
117
|
+
@@token = value
|
118
|
+
end
|
119
|
+
|
117
120
|
def businesses
|
118
121
|
get('user/' + $cfg['user.name'] + '/membership/')
|
119
122
|
end
|
data/lib/MrMurano/Config.rb
CHANGED
@@ -9,7 +9,6 @@ module MrMurano
|
|
9
9
|
# env from ENV['MR_CONFIGFILE']
|
10
10
|
# project .mrmuranorc at project dir
|
11
11
|
# user .mrmuranorc at $HOME
|
12
|
-
# system .mrmuranorc at /etc
|
13
12
|
# defaults Internal hardcoded defaults
|
14
13
|
#
|
15
14
|
ConfigFile = Struct.new(:kind, :path, :data) do
|
@@ -34,12 +33,10 @@ module MrMurano
|
|
34
33
|
attr :paths
|
35
34
|
attr_reader :projectDir
|
36
35
|
|
37
|
-
CFG_SCOPES=%w{internal specified env project
|
36
|
+
CFG_SCOPES=%w{internal specified env project user defaults}.map{|i| i.to_sym}.freeze
|
38
37
|
CFG_FILE_NAME = '.mrmuranorc'.freeze
|
39
|
-
CFG_PRVT_NAME = '.mrmuranorc.private'.freeze # Going away.
|
40
38
|
CFG_DIR_NAME = '.mrmurano'.freeze
|
41
39
|
CFG_ALTRC_NAME = '.mrmurano/config'.freeze
|
42
|
-
CFG_SYS_NAME = '/etc/mrmuranorc'.freeze # Going away.
|
43
40
|
|
44
41
|
def initialize
|
45
42
|
@paths = []
|
@@ -55,19 +52,13 @@ module MrMurano
|
|
55
52
|
end
|
56
53
|
@projectDir = findProjectDir()
|
57
54
|
unless @projectDir.nil? then
|
58
|
-
if (@projectDir + CFG_PRVT_NAME).exist? then
|
59
|
-
say_warning "!!! Using .mrmuranorc.private is deprecated"
|
60
|
-
end
|
61
|
-
@paths << ConfigFile.new(:private, @projectDir + CFG_PRVT_NAME)
|
62
55
|
@paths << ConfigFile.new(:project, @projectDir + CFG_FILE_NAME)
|
63
56
|
fixModes(@projectDir + CFG_DIR_NAME)
|
57
|
+
else
|
58
|
+
@paths << ConfigFile.new(:project, Pathname.new(Dir.home) + CFG_FILE_NAME)
|
64
59
|
end
|
65
60
|
@paths << ConfigFile.new(:user, Pathname.new(Dir.home) + CFG_FILE_NAME)
|
66
61
|
fixModes(Pathname.new(Dir.home) + CFG_DIR_NAME)
|
67
|
-
if Pathname.new(CFG_SYS_NAME).exist? then
|
68
|
-
say_warning "!!! Using #{CFG_SYS_NAME} is deprecated"
|
69
|
-
@paths << ConfigFile.new(:system, Pathname.new(CFG_SYS_NAME))
|
70
|
-
end
|
71
62
|
@paths << ConfigFile.new(:defaults, nil, IniFile.new())
|
72
63
|
|
73
64
|
|
@@ -89,6 +80,8 @@ module MrMurano
|
|
89
80
|
set('location.cors', 'cors.yaml', :defaults)
|
90
81
|
set('location.specs', 'specs', :defaults)
|
91
82
|
|
83
|
+
set('sync.bydefault', SyncRoot.bydefault.join(' '), :defaults)
|
84
|
+
|
92
85
|
set('files.default_page', 'index.html', :defaults)
|
93
86
|
set('files.searchFor', '**/*', :defaults)
|
94
87
|
set('files.ignoring', '', :defaults)
|
@@ -105,7 +98,11 @@ module MrMurano
|
|
105
98
|
|
106
99
|
set('product.spec', 'resources.yaml', :defaults)
|
107
100
|
|
108
|
-
|
101
|
+
if Gem.win_platform? then
|
102
|
+
set('diff.cmd', 'fc', :defaults)
|
103
|
+
else
|
104
|
+
set('diff.cmd', 'diff -u', :defaults)
|
105
|
+
end
|
109
106
|
end
|
110
107
|
|
111
108
|
## Find the root of this project Directory.
|
@@ -119,10 +116,10 @@ module MrMurano
|
|
119
116
|
# - .git/
|
120
117
|
def findProjectDir()
|
121
118
|
result=nil
|
122
|
-
fileNames=[CFG_FILE_NAME,
|
119
|
+
fileNames=[CFG_FILE_NAME, CFG_ALTRC_NAME]
|
123
120
|
dirNames=[CFG_DIR_NAME]
|
124
|
-
home = Pathname.new(Dir.home)
|
125
|
-
pwd = Pathname.new(Dir.pwd)
|
121
|
+
home = Pathname.new(Dir.home).realpath
|
122
|
+
pwd = Pathname.new(Dir.pwd).realpath
|
126
123
|
return nil if home == pwd
|
127
124
|
pwd.dirname.ascend do |i|
|
128
125
|
break unless result.nil?
|
@@ -174,8 +171,6 @@ module MrMurano
|
|
174
171
|
root = @projectDir + CFG_DIR_NAME
|
175
172
|
when :user
|
176
173
|
root = Pathname.new(Dir.home) + CFG_DIR_NAME
|
177
|
-
when :system
|
178
|
-
root = nil
|
179
174
|
when :defaults
|
180
175
|
root = nil
|
181
176
|
end
|
@@ -259,25 +254,6 @@ module MrMurano
|
|
259
254
|
|
260
255
|
end
|
261
256
|
|
262
|
-
##
|
263
|
-
# IF none of -same, then -same; else just the ones listed.
|
264
|
-
def self.checkSAME(opt)
|
265
|
-
unless opt.files or opt.endpoints or opt.modules or
|
266
|
-
opt.eventhandlers or opt.roles or opt.users or opt.spec then
|
267
|
-
opt.files = true
|
268
|
-
opt.endpoints = true
|
269
|
-
opt.modules = true
|
270
|
-
opt.eventhandlers = true
|
271
|
-
end
|
272
|
-
if opt.all then
|
273
|
-
opt.files = true
|
274
|
-
opt.endpoints = true
|
275
|
-
opt.modules = true
|
276
|
-
opt.eventhandlers = true
|
277
|
-
opt.roles = true
|
278
|
-
opt.users = true
|
279
|
-
end
|
280
|
-
end
|
281
257
|
end
|
282
258
|
|
283
259
|
# vim: set ai et sw=2 ts=2 :
|
@@ -114,7 +114,7 @@ module MrMurano
|
|
114
114
|
remove(item[:rid])
|
115
115
|
end
|
116
116
|
r = create(item[:alias], item[:format])
|
117
|
-
raise "Create Failed: #{r}" unless r.
|
117
|
+
raise "Create Failed: #{r}" unless r.empty?
|
118
118
|
end
|
119
119
|
|
120
120
|
## Use alias for doing sync compares
|
@@ -134,11 +134,11 @@ module MrMurano
|
|
134
134
|
from = Pathname.new(from) unless from.kind_of? Pathname
|
135
135
|
debug "#{self.class.to_s}: Getting local items from: #{from}"
|
136
136
|
if not from.exist? then
|
137
|
-
|
137
|
+
warning "Skipping missing #{from.to_s}"
|
138
138
|
return []
|
139
139
|
end
|
140
140
|
unless from.file? then
|
141
|
-
|
141
|
+
warning "Cannot read from #{from.to_s}"
|
142
142
|
return []
|
143
143
|
end
|
144
144
|
|
@@ -149,6 +149,7 @@ module MrMurano
|
|
149
149
|
if here.kind_of?(Hash) and here.has_key?('resources') then
|
150
150
|
here['resources'].map{|i| Hash.transform_keys_to_symbols(i)}
|
151
151
|
else
|
152
|
+
warning "Unexpected data in #{from.to_s}"
|
152
153
|
[]
|
153
154
|
end
|
154
155
|
end
|
@@ -205,7 +206,7 @@ module MrMurano
|
|
205
206
|
##
|
206
207
|
# True if itemA and itemB are different
|
207
208
|
def docmp(itemA, itemB)
|
208
|
-
itemA[:alias]
|
209
|
+
itemA[:alias] != itemB[:alias] or itemA[:format] != itemB[:format]
|
209
210
|
end
|
210
211
|
|
211
212
|
end
|
data/lib/MrMurano/Product.rb
CHANGED
@@ -217,8 +217,7 @@ module MrMurano
|
|
217
217
|
end
|
218
218
|
end
|
219
219
|
else
|
220
|
-
showHttpError(request,
|
221
|
-
raise resp
|
220
|
+
showHttpError(request, resp)
|
222
221
|
end
|
223
222
|
end
|
224
223
|
nil
|
@@ -256,6 +255,7 @@ module MrMurano
|
|
256
255
|
|
257
256
|
##
|
258
257
|
# This is not applicable to Murano. Remove?
|
258
|
+
# :nocov:
|
259
259
|
class ProductModel < ProductBase
|
260
260
|
def initialize
|
261
261
|
super
|
@@ -329,7 +329,6 @@ module MrMurano
|
|
329
329
|
return response.body
|
330
330
|
else
|
331
331
|
showHttpError(request, response)
|
332
|
-
raise response
|
333
332
|
end
|
334
333
|
end
|
335
334
|
|
@@ -354,6 +353,7 @@ module MrMurano
|
|
354
353
|
end
|
355
354
|
|
356
355
|
end
|
356
|
+
# :nocov:
|
357
357
|
|
358
358
|
end
|
359
359
|
# vim: set ai et sw=2 ts=2 :
|
@@ -6,6 +6,7 @@ module MrMurano
|
|
6
6
|
def initialize
|
7
7
|
super
|
8
8
|
@uriparts << 'serviceconfig'
|
9
|
+
@scid = nil
|
9
10
|
end
|
10
11
|
|
11
12
|
def list
|
@@ -57,6 +58,14 @@ module MrMurano
|
|
57
58
|
|
58
59
|
end
|
59
60
|
|
61
|
+
## This is only used for debugging and deciphering APIs.
|
62
|
+
#
|
63
|
+
# There was once a plan for using this to automagically map commands into
|
64
|
+
# services by reading their schema. That plan had too much magic and was too
|
65
|
+
# fragile for real use.
|
66
|
+
#
|
67
|
+
# A much better UI/UX happens with human intervention.
|
68
|
+
# :nocov:
|
60
69
|
class Services < SolutionBase
|
61
70
|
def initialize
|
62
71
|
super
|
@@ -100,8 +109,9 @@ module MrMurano
|
|
100
109
|
calls
|
101
110
|
end
|
102
111
|
end
|
112
|
+
# :nocov:
|
103
113
|
|
104
|
-
|
114
|
+
# Device config interface for the assign commands.
|
105
115
|
class SC_Device < ServiceConfig
|
106
116
|
def initialize
|
107
117
|
super
|
@@ -12,11 +12,15 @@ module MrMurano
|
|
12
12
|
class ServiceBase < SolutionBase
|
13
13
|
|
14
14
|
def mkalias(remote)
|
15
|
+
# :nocov:
|
15
16
|
raise "Needs to be implemented in child"
|
17
|
+
# :nocov:
|
16
18
|
end
|
17
19
|
|
18
20
|
def mkname(remote)
|
21
|
+
# :nocov:
|
19
22
|
raise "Needs to be implemented in child"
|
23
|
+
# :nocov:
|
20
24
|
end
|
21
25
|
|
22
26
|
def list
|
@@ -106,6 +110,7 @@ module MrMurano
|
|
106
110
|
if cacheFile.file? then
|
107
111
|
cacheFile.open('r+') do |io|
|
108
112
|
cache = YAML.load(io)
|
113
|
+
cache = {} unless cache
|
109
114
|
io.rewind
|
110
115
|
cache[local_path.to_s] = entry
|
111
116
|
io << cache.to_yaml
|
@@ -127,6 +132,7 @@ module MrMurano
|
|
127
132
|
ret = nil
|
128
133
|
cacheFile.open('r') do |io|
|
129
134
|
cache = YAML.load(io)
|
135
|
+
return nil unless cache
|
130
136
|
if cache.has_key?(local_path.to_s) then
|
131
137
|
entry = cache[local_path.to_s]
|
132
138
|
debug("For #{local_path}:")
|
@@ -199,6 +205,7 @@ module MrMurano
|
|
199
205
|
@uriparts << 'eventhandler'
|
200
206
|
@itemkey = :alias
|
201
207
|
@location = $cfg['location.eventhandlers']
|
208
|
+
@match_header = /--#EVENT (?<service>\S+) (?<event>\S+)/
|
202
209
|
end
|
203
210
|
|
204
211
|
def mkalias(remote)
|
@@ -259,14 +266,24 @@ module MrMurano
|
|
259
266
|
|
260
267
|
def toRemoteItem(from, path)
|
261
268
|
path = Pathname.new(path) unless path.kind_of? Pathname
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
269
|
+
cur = nil
|
270
|
+
lineno=0
|
271
|
+
path.readlines().each do |line|
|
272
|
+
md = @match_header.match(line)
|
273
|
+
if not md.nil? then
|
274
|
+
# header line.
|
275
|
+
cur = {:service=>md[:service],
|
276
|
+
:event=>md[:event],
|
277
|
+
:local_path=>path,
|
278
|
+
:line=>lineno,
|
279
|
+
:script=>line}
|
280
|
+
elsif not cur.nil? and not cur[:script].nil? then
|
281
|
+
cur[:script] << line
|
282
|
+
end
|
283
|
+
lineno += 1
|
268
284
|
end
|
269
|
-
|
285
|
+
cur[:line_end] = lineno unless cur.nil?
|
286
|
+
cur
|
270
287
|
end
|
271
288
|
|
272
289
|
def synckey(item)
|
@@ -54,7 +54,7 @@ module MrMurano
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
def removelocal(
|
57
|
+
def removelocal(local, item)
|
58
58
|
# needs to append/merge with file
|
59
59
|
# for now, we'll read, modify, write
|
60
60
|
here = []
|
@@ -78,11 +78,11 @@ module MrMurano
|
|
78
78
|
def localitems(from)
|
79
79
|
from = Pathname.new(from) unless from.kind_of? Pathname
|
80
80
|
if not from.exist? then
|
81
|
-
|
81
|
+
warning "Skipping missing #{from.to_s}"
|
82
82
|
return []
|
83
83
|
end
|
84
84
|
unless from.file? then
|
85
|
-
|
85
|
+
warning "Cannot read from #{from.to_s}"
|
86
86
|
return []
|
87
87
|
end
|
88
88
|
|
@@ -106,6 +106,7 @@ module MrMurano
|
|
106
106
|
SyncRoot.add('roles', Role, 'R', %{Roles})
|
107
107
|
|
108
108
|
# …/user
|
109
|
+
# :nocov:
|
109
110
|
class User < UserBase
|
110
111
|
def initialize
|
111
112
|
super
|
@@ -116,7 +117,7 @@ module MrMurano
|
|
116
117
|
# @param modify Bool: True if item exists already and this is changing it
|
117
118
|
def upload(local, remote, modify)
|
118
119
|
# TODO figure out APIs for updating users.
|
119
|
-
|
120
|
+
warning "Updating Users isn't working currently."
|
120
121
|
# post does work if the :password field is set.
|
121
122
|
end
|
122
123
|
|
@@ -124,6 +125,7 @@ module MrMurano
|
|
124
125
|
item[:email]
|
125
126
|
end
|
126
127
|
end
|
128
|
+
# :nocov:
|
127
129
|
SyncRoot.add('users', User, 'U', %{Users})
|
128
130
|
end
|
129
131
|
# vim: set ai et sw=2 ts=2 :
|