MuranoCLI 2.0.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 +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 :
|