diff --git a/ione_server.rb b/ione_server.rb
index 1a20168d..674edf30 100644
--- a/ione_server.rb
+++ b/ione_server.rb
@@ -289,7 +289,7 @@ class IONe
halt 200, {}, ""
end
begin
- unless request.request_method == 'GET' then
+ unless ['GET', 'DELETE'].include? request.request_method then
@request_body = request.body.read
@request_hash = JSON.parse @request_body
@request_hash['params'] = [] if @request_hash['params'].nil?
diff --git a/models/AnsibleDriver.rb b/models/AnsibleDriver.rb
index 5d6672fb..fee59229 100644
--- a/models/AnsibleDriver.rb
+++ b/models/AnsibleDriver.rb
@@ -34,15 +34,6 @@ def crop_zmq_error! # Crops Zmq backtrace and error code from message
end
end
-class Hash
- def duplicate_with_case! to_case = :up # Duplicates each key and value with key up- or down- cased
- self.clone.each do |key, value|
- self[key.send(to_case.to_s + 'case')] = value
- end
- nil
- end
-end
-
class AnsiblePlaybookModel
attr_reader :method, :id
@@ -166,30 +157,19 @@ def message
end
end
-before do # This actions will be performed before any route
- begin
- @one_client = $cloud_auth.client(session[:user]) # Saving OpenNebula client for user
- @one_user = OpenNebula::User.new_with_id(session[:user_id], @one_client) # Saving user object
- rescue => e
- @before_exception = e.message
- end
-end
-
get '/ansible' do # Returns full Ansible Playbooks pool in OpenNebula XML-POOL format
begin
pool = IONe.new($client, $db).ListAnsiblePlaybooks # Array of playbooks
pool.delete_if {|pb| !ansible_check_permissions(pb, @one_user, 0) } # Deletes playbooks, which aren't under user access
pool.map! do | pb | # Adds user and group name to every object
- user, group = OpenNebula::User.new_with_id( pb['uid'], @one_client),
- OpenNebula::Group.new_with_id( pb['gid'], @one_client)
+ user, group = OpenNebula::User.new_with_id( pb['uid'], @client),
+ OpenNebula::Group.new_with_id( pb['gid'], @client)
user.info!; group.info!
pb['vars'] = IONe.new($client, $db).GetAnsiblePlaybookVariables(pb['id'])
pb.merge(
'uname' => user.name, 'gname' => group.name,
'vars' => pb['vars'].nil? ? {} : pb['vars'] )
end
- pool.map{|playbook| playbook.duplicate_with_case! } # Duplicates every key with the same but upcase-d
- # Returns in required format
r(**{
:ANSIBLE_POOL => {
:ANSIBLE => pool
@@ -202,8 +182,7 @@ def message
post '/ansible' do # Allocates new playbook
begin
- data = JSON.parse(@request_body)
- r response: { ANSIBLE: { ID: AnsiblePlaybookModel.new(id:nil, data:data, user:@one_user).id }}
+ r response: { ANSIBLE: { ID: AnsiblePlaybookModel.new(id:nil, data:@request_hash, user:@one_user).id }}
rescue JSON::ParserError # If JSON.parse fails
r error: "Broken data received, unable to parse."
rescue => e
@@ -229,11 +208,11 @@ def message
begin
pb = AnsiblePlaybookModel.new(id:id, user:@one_user) # Getting playbook
# Saving user and group to objects
- user, group = OpenNebula::User.new_with_id( pb.body['uid'], @one_client),
- OpenNebula::Group.new_with_id( pb.body['gid'], @one_client)
+ user, group = OpenNebula::User.new_with_id( pb.body['uid'], @client),
+ OpenNebula::Group.new_with_id( pb.body['gid'], @client)
user.info!; group.info! # Retrieving information about this objects from ONe
pb.body.merge!('uname' => user.name, 'gname' => group.name, 'vars' => pb.vars.nil? ? {} : pb.vars) # Adding user and group names to playbook body
- pb.body.duplicate_with_case! # Duplicates every key with the same but upcase-d
+
r ANSIBLE: pb.body
rescue => e
r error: e.message, backtrace: e.backtrace
@@ -251,8 +230,7 @@ def message
post '/ansible/:id/action' do | id | # Performs action
begin
- data = JSON.parse(@request_body)
- pb = AnsiblePlaybookModel.new(id:id, data:data, user:@one_user)
+ pb = AnsiblePlaybookModel.new(id:id, data:@request_hash, user:@one_user)
r response: pb.call
rescue JSON::ParserError # If JSON.parse fails
@@ -263,11 +241,9 @@ def message
end
post '/ansible/:action' do | action | # Performs actions, which are defined as def self.method for AnsiblePlaybookModel model
- data = JSON.parse(@request_body)
-
begin
if action == 'check_syntax' then
- r response: IONe.new($client, $db).CheckAnsiblePlaybookSyntax( data['body'])
+ r response: IONe.new($client, $db).CheckAnsiblePlaybookSyntax( @request_hash['body'])
else
r response: "Action is not defined"
end
@@ -351,25 +327,16 @@ def message
end
end
- before do # This actions will be performed before any route
- begin
- @one_client = $cloud_auth.client(session[:user]) # Saving OpenNebula client for user
- @one_user = OpenNebula::User.new_with_id(session[:user_id], @one_client) # Saving user object
- rescue => e
- @before_exception = e.message
- end
- end
get '/ansible_process' do
begin
pool = IONe.new($client, $db).ListAnsiblePlaybookProcesses
pool.delete_if {|apc| !@one_user.groups.include?(0) && apc['uid'] != @one_user.id }
pool.map! do | apc | # Adds user name to every object
- user = OpenNebula::User.new_with_id( apc['uid'], @one_client)
+ user = OpenNebula::User.new_with_id( apc['uid'], @client)
user.info!
apc.merge('id' => apc['proc_id'], 'uname' => user.name)
end
- pool.map{|playbook| playbook.duplicate_with_case! } # Duplicates every key with the same but upcase-d
r(**{
:ANSIBLE_PROCESS_POOL => {
@@ -383,8 +350,7 @@ def message
post '/ansible_process' do
begin
- data = JSON.parse(@request_body)
- r response: { ANSIBLE_PROCESS: { ID: AnsiblePlaybookProcessModel.new(id:nil, data:data, user:@one_user).id }}
+ r response: { ANSIBLE_PROCESS: { ID: AnsiblePlaybookProcessModel.new(id:nil, data:@request_hash, user:@one_user).id }}
rescue JSON::ParserError # If JSON.parse fails
r error: "Broken data received, unable to parse."
rescue => e
@@ -397,10 +363,9 @@ def message
begin
apc = AnsiblePlaybookProcessModel.new(id:id, user:@one_user) # Getting playbook
# Saving user and group to objects
- user = OpenNebula::User.new_with_id( apc.body['uid'], @one_client)
+ user = OpenNebula::User.new_with_id( apc.body['uid'], @client)
user.info!
apc.body.merge!('id' => apc.body['proc_id'], 'uname' => user.name) # Retrieving information about this objects from ONe
- apc.body.duplicate_with_case! # Duplicates every key with the same but upcase-d
r ANSIBLE_PROCESS: apc.body
rescue => e
r error: e.message, backtrace: e.backtrace
@@ -422,8 +387,7 @@ def message
post '/ansible_process/:id/action' do | id | # Performs action
begin
- data = JSON.parse(@request_body)
- pb = AnsiblePlaybookProcessModel.new(id:id, data:data, user:@one_user)
+ pb = AnsiblePlaybookProcessModel.new(id:id, data:@request_hash, user:@one_user)
r response: pb.call
rescue JSON::ParserError # If JSON.parse fails
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 271146b7..ad214f3e 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -2158,15 +2158,6 @@
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
"cacache": {
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
@@ -2193,31 +2184,6 @@
"unique-filename": "^1.1.1"
}
},
- "chalk": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
- "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"find-cache-dir": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
@@ -2239,23 +2205,6 @@
"path-exists": "^4.0.0"
}
},
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "loader-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
- "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
- "dev": true,
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- }
- },
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -2320,15 +2269,6 @@
"minipass": "^3.1.1"
}
},
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
"terser-webpack-plugin": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
@@ -2345,17 +2285,6 @@
"terser": "^4.6.12",
"webpack-sources": "^1.4.3"
}
- },
- "vue-loader-v16": {
- "version": "npm:vue-loader@16.1.2",
- "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz",
- "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==",
- "dev": true,
- "requires": {
- "chalk": "^4.1.0",
- "hash-sum": "^2.0.0",
- "loader-utils": "^2.0.0"
- }
}
}
},
@@ -2867,13 +2796,9 @@
"dev": true
},
"argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "requires": {
- "sprintf-js": "~1.0.2"
- }
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"arr-diff": {
"version": "4.0.0",
@@ -4320,6 +4245,11 @@
"q": "^1.1.2"
}
},
+ "codemirror": {
+ "version": "5.59.2",
+ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.59.2.tgz",
+ "integrity": "sha512-/D5PcsKyzthtSy2NNKCyJi3b+htRkoKv3idswR/tR6UAvMNKA7SrmyZy6fOONJxSRs1JlUWEDAbxqfdArbK8iA=="
+ },
"collection-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -4727,6 +4657,25 @@
"parse-json": "^4.0.0"
},
"dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
"parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
@@ -5913,6 +5862,15 @@
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -5942,6 +5900,16 @@
"resolve-from": "^4.0.0"
}
},
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -8983,13 +8951,11 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"js-yaml": {
- "version": "3.14.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
- "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
- "dev": true,
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
+ "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
+ "argparse": "^2.0.1"
}
},
"jsbn": {
@@ -13017,6 +12983,27 @@
"stable": "^0.1.8",
"unquote": "~1.1.1",
"util.promisify": "~1.0.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ }
}
},
"symbol-tree": {
@@ -13862,6 +13849,87 @@
}
}
},
+ "vue-loader-v16": {
+ "version": "npm:vue-loader@16.1.2",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz",
+ "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "hash-sum": "^2.0.0",
+ "loader-utils": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "optional": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "optional": true
+ },
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
"vue-ref": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/vue-ref/-/vue-ref-2.0.0.tgz",
diff --git a/ui/package.json b/ui/package.json
index cdf704f8..bd4e2c32 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -10,7 +10,9 @@
},
"dependencies": {
"ant-design-vue": "^1.7.2",
+ "codemirror": "^5.59.2",
"core-js": "^3.6.5",
+ "js-yaml": "^4.0.0",
"vue": "^2.6.11",
"vue-axios": "^3.2.0",
"vue-router": "^3.2.0",
diff --git a/ui/src/components/playbook/editor.vue b/ui/src/components/playbook/editor.vue
new file mode 100644
index 00000000..2502ce94
--- /dev/null
+++ b/ui/src/components/playbook/editor.vue
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleTagClose(tag)"
+ :color="randomColor()"
+ >
+ {{ tag }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/components/playbook/yaml-editor.vue b/ui/src/components/playbook/yaml-editor.vue
new file mode 100644
index 00000000..9f8de4ec
--- /dev/null
+++ b/ui/src/components/playbook/yaml-editor.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/router/index.js b/ui/src/router/index.js
index 05334949..266dc504 100644
--- a/ui/src/router/index.js
+++ b/ui/src/router/index.js
@@ -44,6 +44,10 @@ const routes = [
path: "hosts",
component: () => import("@/views/dashboard/hosts.vue"),
},
+ {
+ path: "playbooks",
+ component: () => import("@/views/dashboard/playbooks.vue"),
+ },
],
},
];
diff --git a/ui/src/store/index.js b/ui/src/store/index.js
index 3e792723..1bdc67fa 100644
--- a/ui/src/store/index.js
+++ b/ui/src/store/index.js
@@ -1,6 +1,10 @@
import Vue from "vue";
import Vuex from "vuex";
+import axios from "axios";
+
+let config = require("@/config");
+
Vue.use(Vuex);
export default new Vuex.Store({
@@ -9,6 +13,8 @@ export default new Vuex.Store({
loggedIn: false,
},
credentials: "",
+ user_pool: [],
+ group_pool: [],
},
mutations: {
login(state, user) {
@@ -17,10 +23,52 @@ export default new Vuex.Store({
credentials(state, cred) {
state.credentials = cred;
},
+ pool(state, [type, data]) {
+ state[type + "_pool"] = data;
+ },
},
getters: {
credentials: (state) => state.credentials,
+ users: (state) => state.user_pool,
+ groups: (state) => state.group_pool,
+ },
+ actions: {
+ async sync_user_pool({ state, commit }) {
+ let pool = (
+ await axios({
+ method: "post",
+ url: config.CLOUD_API_BASE_URL + "/one.u.pool.to_hash!",
+ auth: state.credentials,
+ data: {},
+ })
+ ).data;
+ if (pool.response) {
+ commit("pool", [
+ "user",
+ pool.response.USER_POOL.USER.map((el) => {
+ return { id: el.ID, name: el.NAME };
+ }),
+ ]);
+ }
+ },
+ async sync_group_pool({ state, commit }) {
+ let pool = (
+ await axios({
+ method: "post",
+ url: config.CLOUD_API_BASE_URL + "/one.g.pool.to_hash!",
+ auth: state.credentials,
+ data: {},
+ })
+ ).data;
+ if (pool.response) {
+ commit("pool", [
+ "group",
+ pool.response.GROUP_POOL.GROUP.map((el) => {
+ return { id: el.ID, name: el.NAME };
+ }),
+ ]);
+ }
+ },
},
- actions: {},
modules: {},
});
diff --git a/ui/src/views/dashboard.vue b/ui/src/views/dashboard.vue
index 6ad9fc95..ecf6c6c6 100644
--- a/ui/src/views/dashboard.vue
+++ b/ui/src/views/dashboard.vue
@@ -43,7 +43,11 @@ const asideBtns = [
{
name: "datastores",
},
-]
+ {
+ name: "Ansible Playbooks",
+ route: "playbooks",
+ },
+];
export default {
data() {
return {
diff --git a/ui/src/views/dashboard/playbooks.vue b/ui/src/views/dashboard/playbooks.vue
new file mode 100644
index 00000000..5ee03c6e
--- /dev/null
+++ b/ui/src/views/dashboard/playbooks.vue
@@ -0,0 +1,281 @@
+
+
+
+
+
+ Add Playbook
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ---
+ Owner
+ Group
+ Others
+
+
+ Use
+
+ updateChecked(e, 0)"
+ />
+
+
+ updateChecked(e, 1)"
+ />
+
+
+ updateChecked(e, 2)"
+ />
+
+
+
+ Manage
+
+ updateChecked(e, 3)"
+ />
+
+
+ updateChecked(e, 4)"
+ />
+
+
+ updateChecked(e, 5)"
+ />
+
+
+
+ Admin
+
+ updateChecked(e, 6)"
+ />
+
+
+ updateChecked(e, 7)"
+ />
+
+
+ updateChecked(e, 8)"
+ />
+
+
+
+
+
+
+
+
+
\ No newline at end of file