MrMurano 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/MrMurano.gemspec +2 -2
- data/README.markdown +25 -3
- data/Rakefile +5 -1
- data/TODO.taskpaper +15 -3
- data/bin/mr +1 -1
- data/lib/MrMurano.rb +4 -0
- data/lib/MrMurano/Account.rb +18 -11
- data/lib/MrMurano/Solution-Endpoint.rb +5 -5
- data/lib/MrMurano/Solution-ServiceConfig.rb +20 -10
- data/lib/MrMurano/Solution-Services.rb +8 -8
- data/lib/MrMurano/Solution.rb +8 -17
- data/lib/MrMurano/cors.rb +57 -0
- data/lib/MrMurano/keystore.rb +105 -0
- data/lib/MrMurano/logs.rb +2 -3
- data/lib/MrMurano/timeseries.rb +84 -0
- data/lib/MrMurano/version.rb +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64252dab4d9f4551bfffef5723875d8aab4c2964
|
4
|
+
data.tar.gz: a24ed29a6a1726b9b54d75e9b34cdd6e5ef596f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85dfd850d6f21f917350de746cb94e57674346fa3d06ac21ef96243491fd7e59cec4e789809a2b8834c0b4549cd71a1802a8d0d143f12fa9b366fad9944fcd20
|
7
|
+
data.tar.gz: 5021da7e66050a1bed213c504bf7405632e5b2a3f5238b1810fb43104c66b7f658d81c42eafcfd3a52fd459dd9bc7a40bd77f9486a72c37469b7d3e67429f56a
|
data/Gemfile
CHANGED
data/MrMurano.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
|
-
|
3
|
+
require_relative 'lib/MrMurano/version.rb'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'MrMurano'
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
|
33
33
|
s.add_development_dependency('bundler', '~> 1.7.6')
|
34
34
|
s.add_development_dependency('rspec', '~> 3.2')
|
35
|
-
s.add_development_dependency('rake')
|
35
|
+
s.add_development_dependency('rake', '~> 10.1.1')
|
36
36
|
end
|
37
37
|
|
38
38
|
|
data/README.markdown
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# MrMurano
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/MrMurano.svg)](https://badge.fury.io/rb/MrMurano)
|
4
|
+
[![Build Status](https://travis-ci.org/tadpol/MrMurano.svg?branch=master)](https://travis-ci.org/tadpol/MrMurano)
|
4
5
|
|
5
6
|
Do more from the command line with [Murano](https://exosite.com/platform/)
|
6
7
|
|
@@ -11,15 +12,13 @@ To start from an existing project in Murano
|
|
11
12
|
mkdir myproject
|
12
13
|
cd myproject
|
13
14
|
mr config solution.id XXXXXX
|
14
|
-
mr syncdown
|
15
|
+
mr syncdown -V
|
15
16
|
```
|
16
17
|
|
17
18
|
Do stuff, see what changed: `mr status` or `mr diff`.
|
18
19
|
Then deploy with `mr syncup`
|
19
20
|
|
20
21
|
|
21
|
-
|
22
|
-
|
23
22
|
## Install
|
24
23
|
|
25
24
|
```
|
@@ -32,6 +31,29 @@ Or
|
|
32
31
|
|
33
32
|
## Features
|
34
33
|
|
34
|
+
### Logs
|
35
|
+
|
36
|
+
You can monitor the log messages from your solution with the `mr logs --follow`.
|
37
|
+
Or quickly get the last few with `mr logs`
|
38
|
+
|
39
|
+
MrMurano does a few things to make your log output easier to follow.
|
40
|
+
- Adds color to easily see where each log message starts.
|
41
|
+
- Reformats the timestamps to be in local time.
|
42
|
+
- Finds JSON blobs and pretty prints them.
|
43
|
+
|
44
|
+
All of these can be toggled with command line options.
|
45
|
+
|
46
|
+
### Keystore
|
47
|
+
|
48
|
+
To aid with debugging, MrMurano has direct access to a solution's Keystore service.
|
49
|
+
|
50
|
+
To see all of the keys in the current solution: `mr keystore`
|
51
|
+
|
52
|
+
### Timeseries
|
53
|
+
|
54
|
+
To aid with debugging, MrMurano has direct access to a solution's Timeseries service.
|
55
|
+
|
56
|
+
|
35
57
|
### Sub-directories
|
36
58
|
|
37
59
|
For the endpoints, modules, and eventhandlers directories. The can contain both
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
-
|
3
|
+
task :default => [:test]
|
4
4
|
|
5
5
|
# TODO: figure out better way to test.
|
6
6
|
desc "Install gem in user dir"
|
@@ -21,5 +21,9 @@ task :run do
|
|
21
21
|
sh %{ruby -Ilib bin/mr }
|
22
22
|
end
|
23
23
|
|
24
|
+
|
25
|
+
task :test do
|
26
|
+
end
|
27
|
+
|
24
28
|
# vim: set sw=4 ts=4 :
|
25
29
|
|
data/TODO.taskpaper
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
Readme:
|
2
|
+
- Add more walk-thrus of common actions. (create new solution, …)
|
1
3
|
|
2
4
|
Commands:
|
3
5
|
- Status will show things have changes when they don’t.
|
@@ -11,28 +13,38 @@ Account:
|
|
11
13
|
Endpoints:
|
12
14
|
- Add support for multiple endpoints in one file (maybe)
|
13
15
|
- Add directory support like in modules @done(2016-07-26)
|
14
|
-
|
16
|
+
|
15
17
|
Files:
|
18
|
+
- Add ignore patterns to config
|
16
19
|
- Switch to mime-types v3
|
17
20
|
- Fix upload. @done(2016-08-01)
|
18
21
|
- Files won't update, they always delete then add. @done(2016-07-28)
|
19
22
|
|
20
|
-
Users:
|
23
|
+
Users and Roles:
|
21
24
|
Much of this is stuck until we get more docs on the User/Role management
|
22
25
|
- Figure out how to upload (create and update) user info.
|
23
26
|
- Figure out how to add Roles to Users in the local data and upload it.
|
24
27
|
- Fix diff for Users and Roles.
|
25
28
|
- Have hash keys in the yaml be strings not symbols. (don't start with colon) @done(2016-07-27)
|
26
29
|
|
30
|
+
CORS:
|
31
|
+
- Get working with sync up/down.
|
32
|
+
- GET&PUT /cors data @done(2016-09-08)
|
33
|
+
|
27
34
|
Product:
|
28
35
|
- Need to add way to set the product ID on a device eventhandler. @done(2016-08-01)
|
29
36
|
|
30
37
|
Config:
|
31
38
|
- Think about adding dev,staging,prod system; how would that work?
|
32
39
|
Would it work ok to just use the --configfile option?
|
40
|
+
I'm thinking so. To the point of dropping the :private scope.
|
41
|
+
- Add ENV support for some (or all?) options.
|
42
|
+
At least the --configfile option. (and --config option)
|
43
|
+
- Maybe add dotenv support.
|
33
44
|
|
34
45
|
SolutionBase:
|
35
46
|
- All network traffic is serialized. Make some parallel.
|
47
|
+
- JSON parse should use symbols for keys. @done(2016-09-01)
|
36
48
|
- Add the --curl verbose option. @done(2016-08-12)
|
37
49
|
- Rebuild how local names and paths are computed from remote items. @done(2016-07-27)
|
38
50
|
|
@@ -41,7 +53,7 @@ Bundles:
|
|
41
53
|
- Work on design @done(2016-08-09)
|
42
54
|
Thinking of something like VIM bundles. A directory of directories. Each with a
|
43
55
|
manafest file? (maybe) A Bundle is a group of modules, endpoints, static files
|
44
|
-
and the other things.
|
56
|
+
and the other things.
|
45
57
|
|
46
58
|
There needs to be some layering logic added, where the bundles are stacked and
|
47
59
|
then the top-level files are stack on top of that. This builds the final map of
|
data/bin/mr
CHANGED
@@ -40,7 +40,7 @@ $cfg.load
|
|
40
40
|
# Basic command support is:
|
41
41
|
# - read/write config file in [Project, User, System] (all are optional)
|
42
42
|
# - Introspection for tab completion.
|
43
|
-
# - Look for tools in PATH that are +x and "mr-foo..."
|
43
|
+
# - Look for tools in PATH that are +x and "mr-foo..."
|
44
44
|
|
45
45
|
|
46
46
|
# Look for plug-ins
|
data/lib/MrMurano.rb
CHANGED
@@ -8,7 +8,11 @@ require 'MrMurano/Solution-File.rb'
|
|
8
8
|
require 'MrMurano/Solution-Services.rb'
|
9
9
|
require 'MrMurano/Solution-Users.rb'
|
10
10
|
require 'MrMurano/Solution-ServiceConfig.rb'
|
11
|
+
|
12
|
+
require 'MrMurano/cors'
|
13
|
+
require 'MrMurano/keystore.rb'
|
11
14
|
require 'MrMurano/logs.rb'
|
12
15
|
require 'MrMurano/sync.rb'
|
13
16
|
require 'MrMurano/status.rb'
|
17
|
+
require 'MrMurano/timeseries.rb'
|
14
18
|
#require 'MrMurano/shelledCommand'
|
data/lib/MrMurano/Account.rb
CHANGED
@@ -51,6 +51,13 @@ module MrMurano
|
|
51
51
|
end
|
52
52
|
|
53
53
|
class Account
|
54
|
+
def initialize
|
55
|
+
@json_opts = {
|
56
|
+
:allow_nan => true,
|
57
|
+
:symbolize_names => true,
|
58
|
+
:create_additions => false
|
59
|
+
}
|
60
|
+
end
|
54
61
|
|
55
62
|
|
56
63
|
def endPoint(path)
|
@@ -91,8 +98,8 @@ module MrMurano
|
|
91
98
|
response = http.request(request)
|
92
99
|
case response
|
93
100
|
when Net::HTTPSuccess
|
94
|
-
token = JSON.parse(response.body)
|
95
|
-
@token = token[
|
101
|
+
token = JSON.parse(response.body, @json_opts)
|
102
|
+
@token = token[:token]
|
96
103
|
else
|
97
104
|
say_error "No token! because: #{response}"
|
98
105
|
@token = nil
|
@@ -113,7 +120,7 @@ module MrMurano
|
|
113
120
|
response = http.request(request)
|
114
121
|
case response
|
115
122
|
when Net::HTTPSuccess
|
116
|
-
busy = JSON.parse(response.body)
|
123
|
+
busy = JSON.parse(response.body, @json_opts)
|
117
124
|
return busy
|
118
125
|
else
|
119
126
|
raise response
|
@@ -132,7 +139,7 @@ module MrMurano
|
|
132
139
|
response = http.request(request)
|
133
140
|
case response
|
134
141
|
when Net::HTTPSuccess
|
135
|
-
busy = JSON.parse(response.body)
|
142
|
+
busy = JSON.parse(response.body, @json_opts)
|
136
143
|
return busy
|
137
144
|
else
|
138
145
|
raise response
|
@@ -151,7 +158,7 @@ module MrMurano
|
|
151
158
|
response = http.request(request)
|
152
159
|
case response
|
153
160
|
when Net::HTTPSuccess
|
154
|
-
busy = JSON.parse(response.body)
|
161
|
+
busy = JSON.parse(response.body, @json_opts)
|
155
162
|
return busy
|
156
163
|
else
|
157
164
|
raise response
|
@@ -180,9 +187,9 @@ command :account do |c|
|
|
180
187
|
if options.businesses then
|
181
188
|
data = acc.businesses
|
182
189
|
if options.idonly then
|
183
|
-
say data.map{|row| row[
|
190
|
+
say data.map{|row| row[:bizid]}.join(' ')
|
184
191
|
else
|
185
|
-
busy = data.map{|row| [row[
|
192
|
+
busy = data.map{|row| [row[:bizid], row[:role], row[:name]]}
|
186
193
|
table = Terminal::Table.new :rows => busy, :headings => ['Biz ID', 'Role', 'Name']
|
187
194
|
say table
|
188
195
|
end
|
@@ -190,9 +197,9 @@ command :account do |c|
|
|
190
197
|
elsif options.products then
|
191
198
|
data = acc.products
|
192
199
|
if options.idonly then
|
193
|
-
say data.map{|row| row[
|
200
|
+
say data.map{|row| row[:pid]}.join(' ')
|
194
201
|
else
|
195
|
-
busy = data.map{|r| [r[
|
202
|
+
busy = data.map{|r| [r[:label], r[:type], r[:pid], r[:modelId]]}
|
196
203
|
table = Terminal::Table.new :rows => busy, :headings => ['Label', 'Type', 'PID', 'ModelID']
|
197
204
|
say table
|
198
205
|
end
|
@@ -200,9 +207,9 @@ command :account do |c|
|
|
200
207
|
elsif options.solutions then
|
201
208
|
data = acc.solutions
|
202
209
|
if options.idonly then
|
203
|
-
say data.map{|row| row[
|
210
|
+
say data.map{|row| row[:apiId]}.join(' ')
|
204
211
|
else
|
205
|
-
busy = data.map{|r| [r[
|
212
|
+
busy = data.map{|r| [r[:apiId], r[:domain], r[:type], r[:sid]]}
|
206
213
|
table = Terminal::Table.new :rows => busy, :headings => ['API ID', 'Domain', 'Type', 'SID']
|
207
214
|
say table
|
208
215
|
end
|
@@ -20,16 +20,16 @@ module MrMurano
|
|
20
20
|
|
21
21
|
def fetch(id)
|
22
22
|
ret = get('/' + id.to_s)
|
23
|
-
aheader = ret[
|
24
|
-
dheader = /^--#ENDPOINT (?i:#{ret[
|
25
|
-
rheader = %{--#ENDPOINT #{ret[
|
23
|
+
aheader = ret[:script].lines.first.chomp
|
24
|
+
dheader = /^--#ENDPOINT (?i:#{ret[:method]}) #{ret[:path]}$/
|
25
|
+
rheader = %{--#ENDPOINT #{ret[:method]} #{ret[:path]}\n}
|
26
26
|
if block_given? then
|
27
27
|
yield rheader unless dheader =~ aheader
|
28
|
-
yield ret[
|
28
|
+
yield ret[:script]
|
29
29
|
else
|
30
30
|
res = ''
|
31
31
|
res << rheader unless dheader =~ aheader
|
32
|
-
res << ret[
|
32
|
+
res << ret[:script]
|
33
33
|
res
|
34
34
|
end
|
35
35
|
end
|
@@ -9,30 +9,40 @@ module MrMurano
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def list
|
12
|
-
get()[
|
12
|
+
get()[:items]
|
13
13
|
end
|
14
14
|
def fetch(id)
|
15
15
|
get('/' + id.to_s)
|
16
16
|
end
|
17
17
|
|
18
|
+
def scid_for_name(name)
|
19
|
+
name = name.to_s unless name.kind_of? String
|
20
|
+
scr = list().select{|i| i[:service] == name}.first
|
21
|
+
scid = scr[:id]
|
22
|
+
end
|
23
|
+
|
24
|
+
def scid
|
25
|
+
return @scid unless @scid.nil?
|
26
|
+
@scid = scid_for_name(@serviceName)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Below is Device ServiceConfig Specific. Should it be in its own class?
|
18
30
|
|
19
31
|
def assignTriggers(products)
|
20
|
-
|
21
|
-
scid = scr['id'] or scr[:id]
|
32
|
+
scid = scid_for_name('device')
|
22
33
|
|
23
|
-
details =
|
34
|
+
details = fetch(scid)
|
24
35
|
products = [products] unless products.kind_of? Array
|
25
36
|
details[:triggers] = {:pid=>products}
|
26
37
|
|
27
38
|
put('/'+scid, details)
|
28
|
-
|
39
|
+
|
29
40
|
end
|
30
41
|
|
31
42
|
def showTriggers
|
32
|
-
|
33
|
-
scid = scr['id'] or scr[:id]
|
43
|
+
scid = scid_for_name('device')
|
34
44
|
|
35
|
-
details =
|
45
|
+
details = fetch(scid)
|
36
46
|
|
37
47
|
return [] if details[:triggers].nil?
|
38
48
|
details[:triggers][:pid]
|
@@ -57,7 +67,7 @@ command :assign do |c|
|
|
57
67
|
say trigs.join(' ')
|
58
68
|
else
|
59
69
|
acc = MrMurano::Account.new
|
60
|
-
products = acc.products
|
70
|
+
products = acc.products
|
61
71
|
products.select!{|p| trigs.include? p[:pid] }
|
62
72
|
busy = products.map{|r| [r[:label], r[:type], r[:pid], r[:modelId]]}
|
63
73
|
table = Terminal::Table.new :rows => busy, :headings => ['Label', 'Type', 'PID', 'ModelID']
|
@@ -70,7 +80,7 @@ command :assign do |c|
|
|
70
80
|
prid = $cfg['product.id']
|
71
81
|
else
|
72
82
|
acc = MrMurano::Account.new
|
73
|
-
products = acc.products
|
83
|
+
products = acc.products
|
74
84
|
products.select!{|p| p[:label] == prname or p[:pid] == prname }
|
75
85
|
prid = products.map{|p| p[:pid]}
|
76
86
|
end
|
@@ -27,15 +27,15 @@ module MrMurano
|
|
27
27
|
|
28
28
|
def list
|
29
29
|
ret = get()
|
30
|
-
ret[
|
30
|
+
ret[:items]
|
31
31
|
end
|
32
32
|
|
33
33
|
def fetch(name)
|
34
34
|
ret = get('/'+name)
|
35
35
|
if block_given? then
|
36
|
-
yield ret[
|
36
|
+
yield ret[:script]
|
37
37
|
else
|
38
|
-
ret[
|
38
|
+
ret[:script]
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -127,20 +127,20 @@ module MrMurano
|
|
127
127
|
def list
|
128
128
|
ret = get()
|
129
129
|
skiplist = ($cfg['eventhandler.skiplist'] or '').split
|
130
|
-
ret[
|
130
|
+
ret[:items].reject{|i| i.has_key?(:service) and skiplist.include? i[:service] }
|
131
131
|
end
|
132
132
|
|
133
133
|
def fetch(name)
|
134
134
|
ret = get('/'+name)
|
135
|
-
aheader = (ret[
|
136
|
-
dheader = "--#EVENT #{ret[
|
135
|
+
aheader = (ret[:script].lines.first or "").chomp
|
136
|
+
dheader = "--#EVENT #{ret[:service]} #{ret[:event]}"
|
137
137
|
if block_given? then
|
138
138
|
yield dheader + "\n" if aheader != dheader
|
139
|
-
yield ret[
|
139
|
+
yield ret[:script]
|
140
140
|
else
|
141
141
|
res = ''
|
142
142
|
res << dheader + "\n" if aheader != dheader
|
143
|
-
res << ret[
|
143
|
+
res << ret[:script]
|
144
144
|
res
|
145
145
|
end
|
146
146
|
end
|
data/lib/MrMurano/Solution.rb
CHANGED
@@ -10,12 +10,18 @@ module MrMurano
|
|
10
10
|
# This might also be a valid ProductBase.
|
11
11
|
def initialize
|
12
12
|
@token = Account.new.token
|
13
|
+
raise "Not logged in!" if @token.nil?
|
13
14
|
@sid = $cfg['solution.id']
|
14
15
|
raise "No solution!" if @sid.nil?
|
15
16
|
@uriparts = [:solution, @sid]
|
16
17
|
@itemkey = :id
|
17
18
|
@locationbase = $cfg['location.base']
|
18
19
|
@location = nil
|
20
|
+
@json_opts = {
|
21
|
+
:allow_nan => true,
|
22
|
+
:symbolize_names => true,
|
23
|
+
:create_additions => false
|
24
|
+
}
|
19
25
|
end
|
20
26
|
|
21
27
|
def verbose(msg)
|
@@ -70,7 +76,7 @@ module MrMurano
|
|
70
76
|
when Net::HTTPSuccess
|
71
77
|
return {} if response.body.nil?
|
72
78
|
begin
|
73
|
-
return JSON.parse(response.body)
|
79
|
+
return JSON.parse(response.body, @json_opts)
|
74
80
|
rescue
|
75
81
|
return response.body
|
76
82
|
end
|
@@ -276,7 +282,7 @@ module MrMurano
|
|
276
282
|
def syncdown(options=Commander::Command::Options.new)
|
277
283
|
options.asdown = true
|
278
284
|
dt = status(options)
|
279
|
-
into = @locationbase + @location
|
285
|
+
into = @locationbase + @location ###
|
280
286
|
toadd = dt[:toadd]
|
281
287
|
todel = dt[:todel]
|
282
288
|
tomod = dt[:tomod]
|
@@ -396,21 +402,6 @@ module MrMurano
|
|
396
402
|
|
397
403
|
end
|
398
404
|
|
399
|
-
# …/serviceconfig
|
400
|
-
class ServiceConfig < SolutionBase
|
401
|
-
def initialize
|
402
|
-
super
|
403
|
-
@uriparts << 'serviceconfig'
|
404
|
-
end
|
405
|
-
|
406
|
-
def list
|
407
|
-
get()['items']
|
408
|
-
end
|
409
|
-
def fetch(id)
|
410
|
-
get('/' + id.to_s)
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
405
|
end
|
415
406
|
|
416
407
|
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
module MrMurano
|
3
|
+
class Cors < SolutionBase
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@uriparts << 'cors'
|
7
|
+
@location = $cfg['location.cors']
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch()
|
11
|
+
ret = get()
|
12
|
+
ret[:cors]
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: fill out other metheds so this could be part of sync up/down.
|
16
|
+
|
17
|
+
##
|
18
|
+
# Upload CORS
|
19
|
+
# :local path to file to push
|
20
|
+
# :remote hash of method and endpoint path (ignored for now)
|
21
|
+
def upload(local, remote)
|
22
|
+
local = Pathname.new(local) unless local.kind_of? Pathname
|
23
|
+
raise "no file" unless local.exist?
|
24
|
+
|
25
|
+
local.open do |io|
|
26
|
+
data = YAML.load(io)
|
27
|
+
put('', data)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def tolocalpath(into, item)
|
32
|
+
into
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
command :cors do |c|
|
38
|
+
c.syntax = %{mr cors [options]}
|
39
|
+
c.description = %{Get or set the CORS for the solution.}
|
40
|
+
c.option '-f','--file FILE', String, %{File to set CORS from}
|
41
|
+
|
42
|
+
c.action do |args,options|
|
43
|
+
sol = MrMurano::Cors.new
|
44
|
+
|
45
|
+
if options.file then
|
46
|
+
#set
|
47
|
+
pp sol.upload(options.file, {})
|
48
|
+
else
|
49
|
+
# get
|
50
|
+
ret = sol.fetch()
|
51
|
+
puts ret
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,105 @@
|
|
1
|
+
|
2
|
+
module MrMurano
|
3
|
+
class Keystore < ServiceConfig
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@serviceName = 'keystore'
|
7
|
+
end
|
8
|
+
|
9
|
+
def keyinfo
|
10
|
+
ret = get("/#{scid}/call/info")
|
11
|
+
end
|
12
|
+
|
13
|
+
def listkeys
|
14
|
+
ret = get("/#{scid}/call/list")
|
15
|
+
ret[:keys]
|
16
|
+
end
|
17
|
+
|
18
|
+
def getkey(key)
|
19
|
+
ret = post("/#{scid}/call/get", {:key=>key})
|
20
|
+
ret[:value]
|
21
|
+
end
|
22
|
+
|
23
|
+
def setkey(key, value)
|
24
|
+
post("/#{scid}/call/set", { :key=>key, :value=>value })
|
25
|
+
end
|
26
|
+
|
27
|
+
def delkey(key)
|
28
|
+
post("/#{scid}/call/delete", { :key=>key})
|
29
|
+
end
|
30
|
+
|
31
|
+
def command(key, cmd, args)
|
32
|
+
post("/#{scid}/call/command", {:key=>key, :command=>cmd, :args=>args})
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
command 'keystore info' do |c|
|
39
|
+
c.syntax = %{mr keystore info}
|
40
|
+
c.description = %{Show info about the Keystore}
|
41
|
+
c.action do |args,options|
|
42
|
+
sol = MrMurano::Keystore.new
|
43
|
+
pp sol.keyinfo
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
command 'keystore list' do |c|
|
48
|
+
c.syntax = %{mr keystore list}
|
49
|
+
c.description = %{List all of the keys in the Keystore}
|
50
|
+
c.action do |args,options|
|
51
|
+
sol = MrMurano::Keystore.new
|
52
|
+
sol.listkeys.each do |key|
|
53
|
+
puts key
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
alias_command :keystore, 'keystore list'
|
58
|
+
|
59
|
+
command 'keystore get' do |c|
|
60
|
+
c.syntax = %{mr keystore get <key>}
|
61
|
+
c.description = %{Get the value of a key in the Keystore}
|
62
|
+
c.action do |args,options|
|
63
|
+
sol = MrMurano::Keystore.new
|
64
|
+
ret = sol.getkey(args[0])
|
65
|
+
puts ret
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
command 'keystore set' do |c|
|
70
|
+
c.syntax = %{mr keystore set <key> <value...>}
|
71
|
+
c.description = %{Set teh value of a key in the Keystore}
|
72
|
+
c.action do |args,options|
|
73
|
+
sol = MrMurano::Keystore.new
|
74
|
+
sol.setkey(args[0], args[1..-1].join(' '))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
command 'keystore delete' do |c|
|
79
|
+
c.syntax = %{mr keystore delete <key>}
|
80
|
+
c.description = %{Delete a key from the Keystore}
|
81
|
+
c.action do |args,options|
|
82
|
+
sol = MrMurano::Keystore.new
|
83
|
+
sol.delkey(args[0])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
alias_command 'keystore rm', 'keystore delete'
|
87
|
+
|
88
|
+
command 'keystore command' do |c|
|
89
|
+
c.syntax = %{mr keystore command <key> <command> <args...>}
|
90
|
+
c.description = %{Call some Redis commands in the Keystore.
|
91
|
+
|
92
|
+
Only a subset of all Redis commands is supported.
|
93
|
+
See http://docs.exosite.com/murano/services/keystore/#command for current list.
|
94
|
+
}
|
95
|
+
c.example %{mr keystore command mykey lpush myvalue}, %{Push a value onto list}
|
96
|
+
c.example %{mr keystore command mykey lpush A B C}, %{Push three values onto list}
|
97
|
+
c.example %{mr keystore command mykey lrem 0 B}, %{Remove all B values from list}
|
98
|
+
c.action do |args,options|
|
99
|
+
sol = MrMurano::Keystore.new
|
100
|
+
pp sol.command(args[0], args[1], args[2..-1])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
alias_command 'keystore cmd', 'keystore command'
|
104
|
+
|
105
|
+
# vim: set ai et sw=2 ts=2 :
|
data/lib/MrMurano/logs.rb
CHANGED
@@ -22,8 +22,8 @@ command :logs do |c|
|
|
22
22
|
begin
|
23
23
|
ret = sol.get('/logs') # TODO: ('/logs?polling=true') Currently ignored.
|
24
24
|
|
25
|
-
if ret.kind_of?(Hash) and ret.has_key?(
|
26
|
-
ret[
|
25
|
+
if ret.kind_of?(Hash) and ret.has_key?(:items) then
|
26
|
+
ret[:items].reverse.each do |line|
|
27
27
|
curtime = ""
|
28
28
|
if line.kind_of?(String) then
|
29
29
|
|
@@ -53,7 +53,6 @@ command :logs do |c|
|
|
53
53
|
out = line
|
54
54
|
|
55
55
|
elsif line.kind_of?(Hash) then
|
56
|
-
line = Hash.transform_keys_to_symbols(line)
|
57
56
|
out=""
|
58
57
|
|
59
58
|
out << "[#{line[:subject]}]".color(:red).background(:aliceblue)
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
module MrMurano
|
3
|
+
class Timeseries < ServiceConfig
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@serviceName = 'timeseries'
|
7
|
+
end
|
8
|
+
|
9
|
+
def query(query)
|
10
|
+
post("/#{scid}/call/query", {:q=>query})
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(writestr)
|
14
|
+
post("/#{scid}/call/write", { :q=>writestr })
|
15
|
+
end
|
16
|
+
|
17
|
+
def command(cmd)
|
18
|
+
post("/#{scid}/call/command", { :q=>cmd})
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
command 'timeseries query' do |c|
|
25
|
+
c.syntax = %{mr timeseries query <query string>}
|
26
|
+
c.description = %{Query the timeseries database}
|
27
|
+
c.option '--[no-]json', %{Display results as raw json}
|
28
|
+
#c.option '--csv', %{Display results as csv}
|
29
|
+
# Should get a CSV formatter to make sure cells are properly escapped.
|
30
|
+
c.action do |args,options|
|
31
|
+
options.defalts :json=>false
|
32
|
+
sol = MrMurano::Timeseries.new
|
33
|
+
ret = sol.query args.join(' ')
|
34
|
+
if options.json then
|
35
|
+
puts ret.to_json
|
36
|
+
else
|
37
|
+
(ret[:results] or []).each do |res|
|
38
|
+
(res[:series] or []).each do |ser|
|
39
|
+
cols = ser[:columns]
|
40
|
+
table = Terminal::Table.new :title=>ser[:name], :headings=>cols, :rows=>ser[:values]
|
41
|
+
puts table
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# If nothing displayed, Format wasn't what we expected, so do what?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias_command :tsq, 'timeseries query'
|
49
|
+
|
50
|
+
command 'timeseries write' do |c|
|
51
|
+
c.syntax = %{mr timeseries <write string>}
|
52
|
+
c.description = %{Write data into the timeseries database}
|
53
|
+
c.option '--[no-]json', %{Display results as raw json}
|
54
|
+
c.action do |args,options|
|
55
|
+
options.defalts :json=>false
|
56
|
+
sol = MrMurano::Timeseries.new
|
57
|
+
ret = sol.write args.join(' ')
|
58
|
+
if options.json then
|
59
|
+
puts ret.to_json
|
60
|
+
else
|
61
|
+
pp ret
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
alias_command :tsw, 'timeseries write'
|
66
|
+
|
67
|
+
command 'timeseries command' do |c|
|
68
|
+
c.syntax = %{mr timeseries command <db command>}
|
69
|
+
c.description = %{Execute a non-query command in the database}
|
70
|
+
c.option '--[no-]json', %{Display results as raw json}
|
71
|
+
c.action do |args,options|
|
72
|
+
options.defalts :json=>false
|
73
|
+
sol = MrMurano::Timeseries.new
|
74
|
+
ret = sol.command args.join(' ')
|
75
|
+
if options.json then
|
76
|
+
puts ret.to_json
|
77
|
+
else
|
78
|
+
pp ret
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# vim: set ai et sw=2 ts=2 :
|
data/lib/MrMurano/version.rb
CHANGED
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.
|
4
|
+
version: 1.3.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-09-
|
11
|
+
date: 2016-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: commander
|
@@ -140,16 +140,16 @@ dependencies:
|
|
140
140
|
name: rake
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- -
|
143
|
+
- - ~>
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 10.1.1
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- -
|
150
|
+
- - ~>
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 10.1.1
|
153
153
|
description: "Do more from the command line with Murano\n\n Push and pull data from
|
154
154
|
Murano.\n Get status on what things have changed.\n See a diff of the changes
|
155
155
|
before you push.\n "
|
@@ -161,6 +161,7 @@ extensions: []
|
|
161
161
|
extra_rdoc_files: []
|
162
162
|
files:
|
163
163
|
- .gitignore
|
164
|
+
- .travis.yml
|
164
165
|
- Gemfile
|
165
166
|
- MrMurano.gemspec
|
166
167
|
- README.markdown
|
@@ -176,11 +177,14 @@ files:
|
|
176
177
|
- lib/MrMurano/Solution-Users.rb
|
177
178
|
- lib/MrMurano/Solution.rb
|
178
179
|
- lib/MrMurano/configFile.rb
|
180
|
+
- lib/MrMurano/cors.rb
|
179
181
|
- lib/MrMurano/hash.rb
|
182
|
+
- lib/MrMurano/keystore.rb
|
180
183
|
- lib/MrMurano/logs.rb
|
181
184
|
- lib/MrMurano/shelledCommand.rb
|
182
185
|
- lib/MrMurano/status.rb
|
183
186
|
- lib/MrMurano/sync.rb
|
187
|
+
- lib/MrMurano/timeseries.rb
|
184
188
|
- lib/MrMurano/version.rb
|
185
189
|
homepage: https://github.com/tadpol/MrMurano
|
186
190
|
licenses:
|