MuranoCLI 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.rspec +2 -0
- data/.travis.yml +21 -0
- data/Gemfile +27 -0
- data/LICENSE.txt +19 -0
- data/MuranoCLI.gemspec +50 -0
- data/MuranoCLI.iss +50 -0
- data/README.markdown +208 -0
- data/Rakefile +188 -0
- data/TODO.taskpaper +122 -0
- data/bin/mr +8 -0
- data/bin/murano +84 -0
- data/docs/demo.md +109 -0
- data/lib/MrMurano/Account.rb +211 -0
- data/lib/MrMurano/Config-Migrate.rb +47 -0
- data/lib/MrMurano/Config.rb +286 -0
- data/lib/MrMurano/Mock.rb +63 -0
- data/lib/MrMurano/Product-1P-Device.rb +145 -0
- data/lib/MrMurano/Product-Resources.rb +195 -0
- data/lib/MrMurano/Product.rb +358 -0
- data/lib/MrMurano/ProjectFile.rb +349 -0
- data/lib/MrMurano/Solution-Cors.rb +46 -0
- data/lib/MrMurano/Solution-Endpoint.rb +177 -0
- data/lib/MrMurano/Solution-File.rb +150 -0
- data/lib/MrMurano/Solution-ServiceConfig.rb +140 -0
- data/lib/MrMurano/Solution-Services.rb +326 -0
- data/lib/MrMurano/Solution-Users.rb +129 -0
- data/lib/MrMurano/Solution.rb +59 -0
- data/lib/MrMurano/SubCmdGroupContext.rb +49 -0
- data/lib/MrMurano/SyncUpDown.rb +565 -0
- data/lib/MrMurano/commands/assign.rb +57 -0
- data/lib/MrMurano/commands/businessList.rb +45 -0
- data/lib/MrMurano/commands/completion.rb +152 -0
- data/lib/MrMurano/commands/config.rb +67 -0
- data/lib/MrMurano/commands/content.rb +130 -0
- data/lib/MrMurano/commands/cors.rb +30 -0
- data/lib/MrMurano/commands/domain.rb +17 -0
- data/lib/MrMurano/commands/gb.rb +33 -0
- data/lib/MrMurano/commands/init.rb +138 -0
- data/lib/MrMurano/commands/keystore.rb +157 -0
- data/lib/MrMurano/commands/logs.rb +78 -0
- data/lib/MrMurano/commands/mock.rb +63 -0
- data/lib/MrMurano/commands/password.rb +88 -0
- data/lib/MrMurano/commands/postgresql.rb +41 -0
- data/lib/MrMurano/commands/product.rb +14 -0
- data/lib/MrMurano/commands/productCreate.rb +39 -0
- data/lib/MrMurano/commands/productDelete.rb +33 -0
- data/lib/MrMurano/commands/productDevice.rb +84 -0
- data/lib/MrMurano/commands/productDeviceIdCmds.rb +86 -0
- data/lib/MrMurano/commands/productList.rb +45 -0
- data/lib/MrMurano/commands/productWrite.rb +27 -0
- data/lib/MrMurano/commands/show.rb +80 -0
- data/lib/MrMurano/commands/solution.rb +14 -0
- data/lib/MrMurano/commands/solutionCreate.rb +39 -0
- data/lib/MrMurano/commands/solutionDelete.rb +34 -0
- data/lib/MrMurano/commands/solutionList.rb +45 -0
- data/lib/MrMurano/commands/status.rb +92 -0
- data/lib/MrMurano/commands/sync.rb +60 -0
- data/lib/MrMurano/commands/timeseries.rb +115 -0
- data/lib/MrMurano/commands/tsdb.rb +271 -0
- data/lib/MrMurano/commands/usage.rb +23 -0
- data/lib/MrMurano/commands/zshcomplete.erb +112 -0
- data/lib/MrMurano/commands.rb +32 -0
- data/lib/MrMurano/hash.rb +20 -0
- data/lib/MrMurano/http.rb +153 -0
- data/lib/MrMurano/makePretty.rb +75 -0
- data/lib/MrMurano/schema/pf-v1.0.0.yaml +114 -0
- data/lib/MrMurano/schema/sf-v0.2.0.yaml +77 -0
- data/lib/MrMurano/schema/sf-v0.3.0.yaml +78 -0
- data/lib/MrMurano/template/mock.erb +9 -0
- data/lib/MrMurano/template/projectFile.murano.erb +81 -0
- data/lib/MrMurano/verbosing.rb +99 -0
- data/lib/MrMurano/version.rb +4 -0
- data/lib/MrMurano.rb +20 -0
- data/spec/Account-Passwords_spec.rb +242 -0
- data/spec/Account_spec.rb +272 -0
- data/spec/ConfigFile_spec.rb +50 -0
- data/spec/ConfigMigrate_spec.rb +89 -0
- data/spec/Config_spec.rb +409 -0
- data/spec/Http_spec.rb +204 -0
- data/spec/MakePretties_spec.rb +118 -0
- data/spec/Mock_spec.rb +53 -0
- data/spec/ProductBase_spec.rb +113 -0
- data/spec/ProductContent_spec.rb +162 -0
- data/spec/ProductResources_spec.rb +329 -0
- data/spec/Product_1P_Device_spec.rb +202 -0
- data/spec/Product_1P_RPC_spec.rb +175 -0
- data/spec/Product_spec.rb +153 -0
- data/spec/ProjectFile_spec.rb +324 -0
- data/spec/Solution-Cors_spec.rb +164 -0
- data/spec/Solution-Endpoint_spec.rb +581 -0
- data/spec/Solution-File_spec.rb +212 -0
- data/spec/Solution-ServiceConfig_spec.rb +202 -0
- data/spec/Solution-ServiceDevice_spec.rb +176 -0
- data/spec/Solution-ServiceEventHandler_spec.rb +385 -0
- data/spec/Solution-ServiceModules_spec.rb +465 -0
- data/spec/Solution-UsersRoles_spec.rb +207 -0
- data/spec/Solution_spec.rb +92 -0
- data/spec/SyncRoot_spec.rb +83 -0
- data/spec/SyncUpDown_spec.rb +495 -0
- data/spec/Verbosing_spec.rb +279 -0
- data/spec/_workspace.rb +27 -0
- data/spec/cmd_assign_spec.rb +51 -0
- data/spec/cmd_business_spec.rb +59 -0
- data/spec/cmd_common.rb +72 -0
- data/spec/cmd_config_spec.rb +68 -0
- data/spec/cmd_content_spec.rb +71 -0
- data/spec/cmd_cors_spec.rb +50 -0
- data/spec/cmd_device_spec.rb +96 -0
- data/spec/cmd_domain_spec.rb +32 -0
- data/spec/cmd_init_spec.rb +30 -0
- data/spec/cmd_keystore_spec.rb +97 -0
- data/spec/cmd_password_spec.rb +62 -0
- data/spec/cmd_status_spec.rb +239 -0
- data/spec/cmd_syncdown_spec.rb +86 -0
- data/spec/cmd_syncup_spec.rb +62 -0
- data/spec/cmd_usage_spec.rb +36 -0
- data/spec/fixtures/.mrmuranorc +9 -0
- data/spec/fixtures/ProjectFiles/invalid.yaml +9 -0
- data/spec/fixtures/ProjectFiles/only_meta.yaml +24 -0
- data/spec/fixtures/ProjectFiles/with_routes.yaml +27 -0
- data/spec/fixtures/SolutionFiles/0.2.0.json +20 -0
- data/spec/fixtures/SolutionFiles/0.2.0_invalid.json +18 -0
- data/spec/fixtures/SolutionFiles/0.2.json +21 -0
- data/spec/fixtures/SolutionFiles/0.3.0.json +20 -0
- data/spec/fixtures/SolutionFiles/0.3.0_invalid.json +19 -0
- data/spec/fixtures/SolutionFiles/0.3.json +20 -0
- data/spec/fixtures/SolutionFiles/basic.json +20 -0
- data/spec/fixtures/SolutionFiles/secret.json +6 -0
- data/spec/fixtures/configfile +9 -0
- data/spec/fixtures/dumped_config +42 -0
- data/spec/fixtures/mrmuranorc_deleted_bob +8 -0
- data/spec/fixtures/mrmuranorc_tool_bob +3 -0
- data/spec/fixtures/product_spec_files/example.exoline.spec.yaml +116 -0
- data/spec/fixtures/product_spec_files/example.murano.spec.yaml +14 -0
- data/spec/fixtures/product_spec_files/gwe.exoline.spec.yaml +21 -0
- data/spec/fixtures/product_spec_files/gwe.murano.spec.yaml +16 -0
- data/spec/fixtures/product_spec_files/lightbulb-no-state.yaml +11 -0
- data/spec/fixtures/product_spec_files/lightbulb.yaml +14 -0
- data/spec/fixtures/roles-three.yaml +11 -0
- data/spec/fixtures/syncable_content/assets/icon.png +0 -0
- data/spec/fixtures/syncable_content/assets/index.html +0 -0
- data/spec/fixtures/syncable_content/assets/js/script.js +0 -0
- data/spec/fixtures/syncable_content/modules/table_util.lua +58 -0
- data/spec/fixtures/syncable_content/routes/manyRoutes.lua +11 -0
- data/spec/fixtures/syncable_content/routes/singleRoute.lua +5 -0
- data/spec/fixtures/syncable_content/services/devdata.lua +18 -0
- data/spec/fixtures/syncable_content/services/timers.lua +4 -0
- data/spec/spec_helper.rb +119 -0
- metadata +498 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'MrMurano/Solution-Cors'
|
3
|
+
|
4
|
+
command :cors do |c|
|
5
|
+
c.syntax = %{murano cors}
|
6
|
+
c.summary = %{Get the CORS for the project.}
|
7
|
+
c.description = %{Get the CORS for the project.
|
8
|
+
|
9
|
+
Set the CORS with `murano cors set`
|
10
|
+
}
|
11
|
+
|
12
|
+
c.action do |args,options|
|
13
|
+
sol = MrMurano::Cors.new
|
14
|
+
ret = sol.fetch()
|
15
|
+
sol.outf ret
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
command 'cors set' do |c|
|
20
|
+
c.syntax = %{murano cors set [<file>]}
|
21
|
+
c.summary = %{Set the CORS for the project.}
|
22
|
+
|
23
|
+
c.action do |args,options|
|
24
|
+
crs = MrMurano::Cors.new
|
25
|
+
file = args.shift
|
26
|
+
crs.upload(file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'MrMurano/Solution'
|
2
|
+
command :domain do |c|
|
3
|
+
c.syntax = %{murano domain}
|
4
|
+
c.summary = %{Print the domain for this solution}
|
5
|
+
c.option '--[no-]raw', %{Don't add scheme}
|
6
|
+
c.action do |args,options|
|
7
|
+
options.default :raw=>true
|
8
|
+
sol = MrMurano::Solution.new
|
9
|
+
ret = sol.info()
|
10
|
+
if options.raw then
|
11
|
+
say ret[:domain]
|
12
|
+
else
|
13
|
+
say "https://#{ret[:domain]}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
# You don't need this.
|
4
|
+
# To use this:
|
5
|
+
# - mkdir -p ~/.mrmurano/plugins
|
6
|
+
# - ln gb.rb ~/.mrmurano/plugins
|
7
|
+
|
8
|
+
command :_gb do |c|
|
9
|
+
c.syntax = %{murano _gb <class> <method> (<args>)}
|
10
|
+
c.summary = %{Call internal class methods directly.}
|
11
|
+
c.description = %{Call internal class methods directly.}
|
12
|
+
|
13
|
+
c.action do |args, options|
|
14
|
+
cls = args[0]
|
15
|
+
meth = args[1].to_sym
|
16
|
+
args.shift(2)
|
17
|
+
|
18
|
+
begin
|
19
|
+
gb = Object::const_get("MrMurano::#{cls}").new
|
20
|
+
if gb.respond_to? meth then
|
21
|
+
pp gb.__send__(meth, *args)
|
22
|
+
else
|
23
|
+
say_error "'#{cls}' doesn't '#{meth}'"
|
24
|
+
end
|
25
|
+
rescue Exception => e
|
26
|
+
say_error e.message
|
27
|
+
pp e
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'MrMurano/Account'
|
2
|
+
require 'MrMurano/Config-Migrate'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
|
6
|
+
command :init do |c|
|
7
|
+
c.syntax = %{murano init}
|
8
|
+
c.summary = %{The easy way to start a project}
|
9
|
+
c.description = %{}
|
10
|
+
|
11
|
+
c.option '--force', %{Override existing business, solution, or product ids}
|
12
|
+
c.option '--[no-]mkdirs', %{Create default directories}
|
13
|
+
|
14
|
+
c.action do |args, options|
|
15
|
+
options.default :force=>false, :mkdirs=>true
|
16
|
+
acc = MrMurano::Account.new
|
17
|
+
puts ''
|
18
|
+
|
19
|
+
if Pathname.new(Dir.pwd).realpath == Pathname.new(Dir.home).realpath then
|
20
|
+
acc.error "Cannot init a project in your HOME directory."
|
21
|
+
exit 2
|
22
|
+
end
|
23
|
+
|
24
|
+
say "Found project base directory at #{$cfg['location.base'].to_s}"
|
25
|
+
puts ''
|
26
|
+
|
27
|
+
# Try to import a .Solutionfile.secret
|
28
|
+
MrMurano::ConfigMigrate.new.import_secret
|
29
|
+
|
30
|
+
# If they have never logged in, then asking for the business.id will also ask
|
31
|
+
# for their username and password.
|
32
|
+
say "Using account #{$cfg['user.name']}"
|
33
|
+
say ''
|
34
|
+
|
35
|
+
# 1. Get business id
|
36
|
+
if not options.force and not $cfg['business.id'].nil? then
|
37
|
+
say "Using Business ID already set to #{$cfg['business.id']}"
|
38
|
+
else
|
39
|
+
bizz = acc.businesses
|
40
|
+
if bizz.count == 1 then
|
41
|
+
bizid = bizz.first
|
42
|
+
say "You are only part of one business; using #{bizid[:name]}"
|
43
|
+
$cfg.set('businesses.id', bizid[:bizid], :project)
|
44
|
+
|
45
|
+
else
|
46
|
+
choose do |menu|
|
47
|
+
menu.prompt = "Select which Business to use:"
|
48
|
+
menu.flow = :columns_across
|
49
|
+
bizz.sort{|a,b| a[:name]<=>b[:name]}.each do |b|
|
50
|
+
menu.choice(b[:name]) do
|
51
|
+
$cfg.set('business.id', b[:bizid], :project)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
puts '' # blank line
|
58
|
+
|
59
|
+
# 2. Get Solution id
|
60
|
+
if not options.force and not $cfg['solution.id'].nil? then
|
61
|
+
say "Using Solution ID already set to #{$cfg['solution.id']}"
|
62
|
+
else
|
63
|
+
solz = acc.solutions
|
64
|
+
if solz.count == 1 then
|
65
|
+
sol = solz.first
|
66
|
+
say "You only have one solution; using #{sol[:domain]}"
|
67
|
+
$cfg.set('solution.id', sol[:apiId], :project)
|
68
|
+
else
|
69
|
+
choose do |menu|
|
70
|
+
menu.prompt = "Select which Solution to use:"
|
71
|
+
menu.flow = :columns_across
|
72
|
+
solz.sort{|a,b| a[:domain]<=>b[:domain]}.each do |s|
|
73
|
+
menu.choice(s[:domain].sub(/\..*$/,'')) do
|
74
|
+
$cfg.set('solution.id', s[:apiId], :project)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
puts '' # blank line
|
81
|
+
|
82
|
+
# 3. Get Product id
|
83
|
+
if not options.force and not $cfg['product.id'].nil? then
|
84
|
+
say "Using Product ID already set to #{$cfg['product.id']}"
|
85
|
+
else
|
86
|
+
podz = acc.products
|
87
|
+
if podz.count == 1 then
|
88
|
+
prd = podz.first
|
89
|
+
say "You only have one product; using #{prd[:label]}"
|
90
|
+
$cfg.set('product.id', prd[:modelId], :project)
|
91
|
+
else
|
92
|
+
choose do |menu|
|
93
|
+
menu.prompt = "Select which Product to use:"
|
94
|
+
menu.flow = :columns_across
|
95
|
+
podz.sort{|a,b| a[:label]<=>b[:label]}.each do |p|
|
96
|
+
menu.choice(p[:label]) do
|
97
|
+
$cfg.set('product.id', p[:modelId], :project)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
puts ''
|
105
|
+
say "Ok, In business ID: #{$cfg['business.id']} using Solution ID: #{$cfg['solution.id']} with Product ID: #{$cfg['product.id']}"
|
106
|
+
|
107
|
+
# If no ProjectFile or Solutionfile, then write a ProjectFile
|
108
|
+
if $project.project_file.nil? then
|
109
|
+
tmpl = File.read(File.join(File.dirname(__FILE__),'..','template','projectFile.murano.erb'))
|
110
|
+
tmpl = ERB.new(tmpl)
|
111
|
+
res = tmpl.result($project.data_binding)
|
112
|
+
prFile = $project['info.name'] + '.murano'
|
113
|
+
say "Writing an initial Project file: #{prFile}"
|
114
|
+
File.open(prFile, 'w') {|io| io << res}
|
115
|
+
end
|
116
|
+
|
117
|
+
if options.mkdirs then
|
118
|
+
base = $cfg['location.base']
|
119
|
+
base = Pathname.new(base) unless base.kind_of? Pathname
|
120
|
+
%w{
|
121
|
+
location.files
|
122
|
+
location.endpoints
|
123
|
+
location.modules
|
124
|
+
location.eventhandlers
|
125
|
+
location.specs
|
126
|
+
}.each do |cfgi|
|
127
|
+
path = $cfg[cfgi]
|
128
|
+
path = Pathname.new(path) unless path.kind_of? Pathname
|
129
|
+
path = base + path
|
130
|
+
path.mkpath unless path.exist?
|
131
|
+
end
|
132
|
+
say "Default directories created"
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'MrMurano/Solution-ServiceConfig'
|
2
|
+
|
3
|
+
module MrMurano
|
4
|
+
class Keystore < ServiceConfig
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@serviceName = 'keystore'
|
8
|
+
end
|
9
|
+
|
10
|
+
def keyinfo
|
11
|
+
call(:info)
|
12
|
+
end
|
13
|
+
|
14
|
+
def listkeys
|
15
|
+
ret = call(:list)
|
16
|
+
ret[:keys]
|
17
|
+
end
|
18
|
+
|
19
|
+
def getkey(key)
|
20
|
+
ret = call(:get, :post, {:key=>key})
|
21
|
+
ret[:value]
|
22
|
+
end
|
23
|
+
|
24
|
+
def setkey(key, value)
|
25
|
+
call(:set, :post, { :key=>key, :value=>value })
|
26
|
+
end
|
27
|
+
|
28
|
+
def delkey(key)
|
29
|
+
call(:delete, :post, {:key=>key})
|
30
|
+
end
|
31
|
+
|
32
|
+
def command(key, cmd, args)
|
33
|
+
call(:command, :post, {:key=>key, :command=>cmd, :args=>args})
|
34
|
+
end
|
35
|
+
|
36
|
+
def clearall()
|
37
|
+
call(:clear, :post, {})
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
command :keystore do |c|
|
44
|
+
c.syntax = %{murano keystore}
|
45
|
+
c.summary = %{About Keystore}
|
46
|
+
c.description = %{The Keystore sub-commands let you interact directly with the Keystore instance
|
47
|
+
in a solution. This allows for easier debugging, being able to quickly get and
|
48
|
+
set data. As well as calling any of the other supported REDIS commands.}
|
49
|
+
c.action do |args, options|
|
50
|
+
::Commander::UI.enable_paging
|
51
|
+
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
command 'keystore clearAll' do |c|
|
56
|
+
c.syntax = %{murano keystore clearAll}
|
57
|
+
c.description = %{Delete all keys in the keystore}
|
58
|
+
c.action do |args,options|
|
59
|
+
sol = MrMurano::Keystore.new
|
60
|
+
sol.clearall
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
command 'keystore info' do |c|
|
65
|
+
c.syntax = %{murano keystore info}
|
66
|
+
c.description = %{Show info about the Keystore}
|
67
|
+
c.action do |args,options|
|
68
|
+
sol = MrMurano::Keystore.new
|
69
|
+
sol.outf sol.keyinfo
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
command 'keystore list' do |c|
|
74
|
+
c.syntax = %{murano keystore list}
|
75
|
+
c.description = %{List all of the keys in the Keystore}
|
76
|
+
c.action do |args,options|
|
77
|
+
sol = MrMurano::Keystore.new
|
78
|
+
sol.outf sol.listkeys
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
command 'keystore get' do |c|
|
83
|
+
c.syntax = %{murano keystore get <key>}
|
84
|
+
c.description = %{Get the value of a key in the Keystore}
|
85
|
+
c.action do |args,options|
|
86
|
+
sol = MrMurano::Keystore.new
|
87
|
+
ret = sol.getkey(args[0])
|
88
|
+
sol.outf ret
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
command 'keystore set' do |c|
|
93
|
+
c.syntax = %{murano keystore set <key> <value...>}
|
94
|
+
c.description = %{Set the value of a key in the Keystore}
|
95
|
+
c.action do |args,options|
|
96
|
+
sol = MrMurano::Keystore.new
|
97
|
+
sol.setkey(args[0], args[1..-1].join(' '))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
command 'keystore delete' do |c|
|
102
|
+
c.syntax = %{murano keystore delete <key>}
|
103
|
+
c.description = %{Delete a key from the Keystore}
|
104
|
+
c.action do |args,options|
|
105
|
+
sol = MrMurano::Keystore.new
|
106
|
+
sol.delkey(args[0])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
alias_command 'keystore rm', 'keystore delete'
|
110
|
+
alias_command 'keystore del', 'keystore delete'
|
111
|
+
|
112
|
+
command 'keystore command' do |c|
|
113
|
+
c.syntax = %{murano keystore command <command> <key> <args...>}
|
114
|
+
c.summary = %{Call some Redis commands in the Keystore}
|
115
|
+
c.description = %{Call some Redis commands in the Keystore.
|
116
|
+
|
117
|
+
Only a subset of all Redis commands is supported.
|
118
|
+
See http://docs.exosite.com/murano/services/keystore/#command for current list.
|
119
|
+
}
|
120
|
+
c.example %{murano keystore command lpush mykey myvalue}, %{Push a value onto list}
|
121
|
+
c.example %{murano keystore command lpush mykey A B C}, %{Push three values onto list}
|
122
|
+
c.example %{murano keystore command lrem mykey 0 B}, %{Remove all B values from list}
|
123
|
+
c.action do |args,options|
|
124
|
+
sol = MrMurano::Keystore.new
|
125
|
+
if args.count < 2 then
|
126
|
+
sol.error "Not enough params"
|
127
|
+
else
|
128
|
+
ret = sol.command(args[1], args[0], args[2..-1])
|
129
|
+
if ret.has_key?(:value) then
|
130
|
+
sol.outf ret[:value]
|
131
|
+
else
|
132
|
+
sol.error "#{ret[:code]}: #{ret.message}"
|
133
|
+
sol.outf ret[:error] if ($cfg['tool.debug'] and ret.has_key?(:error))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
alias_command 'keystore cmd', 'keystore command'
|
139
|
+
|
140
|
+
# A bunch of common REDIS commands that are suported in Murano
|
141
|
+
alias_command 'keystore lpush', 'keystore command', 'lpush'
|
142
|
+
alias_command 'keystore lindex', 'keystore command', 'lindex'
|
143
|
+
alias_command 'keystore llen', 'keystore command', 'llen'
|
144
|
+
alias_command 'keystore linsert', 'keystore command', 'linsert'
|
145
|
+
alias_command 'keystore lrange', 'keystore command', 'lrange'
|
146
|
+
alias_command 'keystore lrem', 'keystore command', 'lrem'
|
147
|
+
alias_command 'keystore lset', 'keystore command', 'lset'
|
148
|
+
alias_command 'keystore ltrim', 'keystore command', 'ltrim'
|
149
|
+
alias_command 'keystore rpop', 'keystore command', 'rpop'
|
150
|
+
alias_command 'keystore rpush', 'keystore command', 'rpush'
|
151
|
+
alias_command 'keystore sadd', 'keystore command', 'sadd'
|
152
|
+
alias_command 'keystore srem', 'keystore command', 'srem'
|
153
|
+
alias_command 'keystore scard', 'keystore command', 'scard'
|
154
|
+
alias_command 'keystore smembers', 'keystore command', 'smembers'
|
155
|
+
alias_command 'keystore spop', 'keystore command', 'spop'
|
156
|
+
|
157
|
+
# vim: set ai et sw=2 ts=2 :
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'MrMurano/Solution'
|
2
|
+
require 'MrMurano/makePretty'
|
3
|
+
|
4
|
+
command :logs do |c|
|
5
|
+
c.syntax = %{murano logs [options]}
|
6
|
+
c.description = %{Get the logs for a solution}
|
7
|
+
c.option '-f','--follow', %{Follow logs from server}
|
8
|
+
c.option('--[no-]color', %{Toggle colorizing of logs}) {
|
9
|
+
Rainbow.enabled = false
|
10
|
+
}
|
11
|
+
c.option '--[no-]pretty', %{Reformat JSON blobs in logs.}
|
12
|
+
c.option '--[no-]localtime', %{Adjust Timestamps to be in local time}
|
13
|
+
c.option '--raw', %{Don't do any formating of the log data}
|
14
|
+
|
15
|
+
c.action do |args,options|
|
16
|
+
options.default :pretty=>true, :localtime=>true, :raw => false
|
17
|
+
|
18
|
+
sol = MrMurano::Solution.new
|
19
|
+
|
20
|
+
if options.follow then
|
21
|
+
# open a lasting connection and continueally feed makePretty()
|
22
|
+
begin
|
23
|
+
sol.get('/logs?polling=true') do |request, http|
|
24
|
+
request["Accept-Encoding"] = "None"
|
25
|
+
http.request(request) do |response|
|
26
|
+
remainder=''
|
27
|
+
response.read_body do |chunk|
|
28
|
+
chunk = remainder + chunk unless remainder.empty?
|
29
|
+
|
30
|
+
# for all complete JSON blobs, make them pretty.
|
31
|
+
chunk.gsub!(/\{(?>[^}{]+|\g<0>)*\}/m) do |m|
|
32
|
+
if options.raw then
|
33
|
+
puts m
|
34
|
+
else
|
35
|
+
begin
|
36
|
+
js = JSON.parse(m, {:allow_nan=>true,
|
37
|
+
:symbolize_names => true,
|
38
|
+
:create_additions=>false})
|
39
|
+
puts MrMurano::Pretties::makePretty(js, options)
|
40
|
+
rescue
|
41
|
+
sol.error '=== JSON parse error, showing raw instead ==='
|
42
|
+
puts m
|
43
|
+
end
|
44
|
+
end
|
45
|
+
'' #remove (we're kinda abusing gsub here.)
|
46
|
+
end
|
47
|
+
|
48
|
+
# is there an incomplete one?
|
49
|
+
if chunk.match(/(\{.*$)/m) then
|
50
|
+
remainder = $1
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
rescue Interrupt => _
|
57
|
+
end
|
58
|
+
|
59
|
+
else
|
60
|
+
ret = sol.get('/logs')
|
61
|
+
|
62
|
+
if ret.kind_of?(Hash) and ret.has_key?(:items) then
|
63
|
+
ret[:items].reverse.each do |line|
|
64
|
+
if options.raw then
|
65
|
+
puts line
|
66
|
+
else
|
67
|
+
puts MrMurano::Pretties::makePretty(line, options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
sol.error "Couldn't get logs: #{ret}"
|
72
|
+
break
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
# vim: set ai et sw=2 ts=2 :
|