MrMurano 1.11.3 → 1.12.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 +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
|
[](https://badge.fury.io/rb/MrMurano)
|
|
4
4
|
[](https://travis-ci.org/tadpol/MrMurano)
|
|
5
|
+
[](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 :
|