Merge branch 'master' of github.com:pcbsd/sysadm

This commit is contained in:
Ken Moore
2016-02-09 09:19:20 -05:00
19 changed files with 1837 additions and 104 deletions

55
.gitignore vendored
View File

@@ -1,43 +1,60 @@
src/Makefile
src/binary/Makefile
src/binary/main.o
src/binary/Makefile
src/binary/sysadm
src/library/Makefile
src/library/NetDevice.o
src/library/libsysadm.so
src/library/libsysadm.so.1
src/library/libsysadm.so.1.0
src/library/libsysadm.so.1.0.0
src/library/Makefile
src/library/NetDevice.o
src/library/sysadm-firewall.o
src/library/sysadm-general.o
src/library/sysadm-lifepreserver.o
src/library/sysadm-network.o
src/library/sysadm-firewall.o
src/library/sysadm-servicemanager.o
src/library/sysadm-systeminfo.o
src/library/sysadm-update.o
src/library/sysadm-usermanager.o
src/Makefile
src/server/AuthorizationManager.o
src/server/Makefile
src/server/WebBackend.o
src/server/WebServer.o
src/server/WebSocket.o
src/server/dispatcher-client.o
src/server/Dispatcher.o
src/server/EventWatcher.o
src/server/LogManager.o
src/server/main.o
src/server/Makefile
src/server/moc_AuthorizationManager.cpp
src/server/moc_AuthorizationManager.o
src/server/moc_WebServer.cpp
src/server/moc_WebServer.o
src/server/moc_WebSocket.cpp
src/server/moc_WebSocket.o
src/server/moc_dispatcher-client.cpp
src/server/moc_dispatcher-client.o
src/server/moc_syscache-client.cpp
src/server/moc_syscache-client.o
src/server/sysadm-server
src/server/syscache-client.o
src/server/EventWatcher.o
src/server/moc_Dispatcher.cpp
src/server/moc_Dispatcher.o
src/server/moc_EventWatcher.cpp
src/server/moc_EventWatcher.o
src/server/moc_SslServer.cpp
src/server/moc_SslServer.o
src/server/moc_syscache-client.cpp
src/server/moc_syscache-client.o
src/server/moc_WebServer.cpp
src/server/moc_WebServer.o
src/server/moc_WebSocket.cpp
src/server/moc_WebSocket.o
src/server/NetDevice.o
src/server/sysadm-beadm.o
src/server/sysadm-firewall.o
src/server/sysadm-general.o
src/server/sysadm-iocage.o
src/server/sysadm-iohyve.o
src/server/sysadm-lifepreserver.o
src/server/sysadm-network.o
src/server/sysadm-server
src/server/sysadm-servicemanager.o
src/server/sysadm-systeminfo.o
src/server/sysadm-systemmanager.o
src/server/sysadm-update.o
src/server/sysadm-usermanager.o
src/server/syscache-client.o
src/server/WebBackend.o
src/server/WebServer.o
src/server/WebSocket.o
tests/node_modules/

View File

@@ -1,18 +1,88 @@
# sysadm
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
Official repo for PC-BSD's sysadm utility and websocket server
- [SysAdm](#sysadm)
- [Required Qt Modules](#required-qt-modules)
- [Building SysAdm](#building-sysadm)
- [Starting SysAdm](#starting-sysadm)
- [API Documentation](#api-documentation)
- [Contributing new API calls](#contributing-new-api-calls)
- [Adding new Classes for API calls](#adding-new-classes-for-api-calls)
- [Testing new API calls / classes](#testing-new-api-calls--classes)
###
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
This repo contains all the Qt5 code necessary to build the following:
# SysAdm
Official repo for PC-BSD's sysadm middleware WebSocket & REST server
This middleware acts as the core for controlling a PC-BSD or FreeBSD <br />
system either locally or remotely via WebSockets or REST.
### Required Qt Modules
```
sysadm-daemon - Backend daemon which handles all middleware / library
requests and functionality
sysadm-ws - Websocket server, which handles incoming requests
for both remote and local wss:// connections
sysadm - Command line interface to send/recv json requests
Qt5 Core (pkg install qt5-core)
Qt5 Concurrent (pkg install qt5-concurrent)
Qt5 Websockets (pkg install qt5-websockets)
```
### Building SysAdm
```
% git clone https://github.com/pcbsd/sysadm.git
% cd sysadm/src
% /usr/local/lib/qt5/bin/qmake -recursive
% make && sudo make install
```
### Starting SysAdm
```
(For WebSockets - Required for SysAdm Client)
% sudo sysrc -f /etc/rc.conf sysadm_websocket_enable="YES"
% sudo service sysadm-websocket start
(Optional for REST)
% sudo sysrc -f /etc/rc.conf sysadm_restserver_enable="YES"
% sudo service sysadm-restserver start
```
### API Documentation
https://api.pcbsd.org
### Contributing new API calls
Adding new API calls to the middleware is very straight-forward, simply <br />
add a new function which accepts JSON in, and returns JSON, then connect <br />
it to the backend.
Example:
https://github.com/pcbsd/sysadm/commit/4d3b590f460d301b9376a063f9407dabfd7c9c66
### Adding new Classes for API calls
Adding a new API class requires tweaking a few more files than a new API call only.
Example:
https://github.com/pcbsd/sysadm/commit/1ba65b33880e2298ade3e5cc4f2718aa6112e44f
### Testing new API calls / classes
Before committing or sending a pull request, you'll need to run our <br />
"api-test.sh" script and confirm it works properly. To do so, first add <br />
your new call and restart the websocket server. Next do the following:
```
% cd sysadm/tests
% ./api-test.sh
```
The api-test script will prompt you to enter username, password, and some <br />
information about which class / API call to run. When that is done, and you <br />
have verified the functionality of your new call you should add the output <br />
of the test script (either from copy-n-paste, or from the file /tmp/api-response) <br />
to your commit. (This will allow us to document the new call / class)

140
api/classes/beadm.rst Normal file
View File

@@ -0,0 +1,140 @@
.. _beadm:
beadm
*****
The beadm class is used to manage boot environments.
Every beadm class request contains the following parameters:
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| **Parameter** | **Value** | **Description** |
| | | |
+=================================+===============+======================================================================================================================+
| id | | any unique value for the request; examples include a hash, checksum, or uuid |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| name | beadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| namespace | sysadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| action | | supported actions include "listbes", "renamebe" |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
The rest of this section provides examples of the available *actions* for each type of request, along with their responses.
.. index:: listbes, beadm
.. _List Boot Environments:
List Boot Environments
======================
The "listbes" action retrieves the list of boot environments. For each boot environment, the response includes its name, its flags (where "R" is active on reboot, "N" is active now and
"-" is inactive), the date it was created, its mount point, its nickname, and its size.
**REST Request**
.. code-block:: json
PUT /sysadm/beadm
{
"action" : "listbes"
}
**WebSocket Request**
.. code-block:: json
{
"name" : "beadm",
"namespace" : "sysadm",
"id" : "fooid",
"args" : {
"action" : "listbes"
}
}
**Response**
.. code-block:: json
{
"args": {
"listbes": {
"11.0-CURRENTJAN2016-up-20160128_150853": {
"active": "NR",
"date": "2016-01-28",
"mount": "/",
"nick": "14:57",
"space": "10.2G"
},
"initial": {
"active": "-",
"date": "2016-01-28",
"mount": "-",
"nick": "07:00",
"space": "1.2G"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: renamebe, beadm
.. _Rename a Boot Environment:
Rename a Boot Environment
=========================
The "renamebe" action renames the specified boot environment. When using this action, specify the new name as the "source" and the boot environment as the "target".
**REST Request**
.. code-block:: json
PUT /sysadm/beadm
{
"source" : "newname",
"action" : "renamebe",
"target" : "bootthingy"
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"name" : "beadm",
"id" : "fooid",
"args" : {
"source" : "newname",
"target" : "bootthingy",
"action" : "renamebe"
}
}
**Response**
.. code-block:: json
{
"args": {
"renamebe": {
"source": "newname",
"target": "bootthingy"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}

View File

@@ -1,7 +0,0 @@
.. _bootenvironments:
bootenvironments
================
Some intro text here...

View File

@@ -20,7 +20,8 @@ Every iocage class request contains the following parameters:
| namespace | sysadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| action | | supported actions include "getdefaultsettings", "listjails", "getjailsettings" |
| action | | supported actions include "getdefaultsettings", "listjails", "getjailsettings", "startjail", "stopjail", |
| | | "capjail", "cleanjails", "cleanreleases", "cleantemplates", "cleanall", "activatepool", and "deactivatepool" |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
@@ -332,6 +333,7 @@ system boot, the jail ID (only applies to running jails), whether or not the jai
"listjails": {
"611c89ae-c43c-11e5-9602-54ee75595566": {
"boot": "off",
"ip4": "-",
"jid": "-",
"state": "down",
"tag": "testjail",
@@ -363,6 +365,7 @@ system boot, the jail ID (only applies to running jails), whether or not the jai
"listjails": {
"611c89ae-c43c-11e5-9602-54ee75595566": {
"boot": "off",
"ip4": "-",
"jid": "-",
"state": "down",
"tag": "testjail",
@@ -648,4 +651,557 @@ The "getjailsettings" action lists all of the settings that apply to the specifi
"name": "response",
"namespace": "sysadm"
}
.. index:: startjail, iocage
.. _Start a Jail:
Start a Jail
============
The "startjail" action starts the specified jail.
.. note:: since a jail can only be started once, you will receive an error if the jail is already running.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "startjail",
"jail" : "test"
}
**REST Response**
.. code-block:: json
{
"args": {
"startjail": {
"test": {
"* Starting 0bf985de-ca0f-11e5-8d45-d05099728dbf (test)": "",
"+ Started (shared IP mode) OK": "",
"+ Starting services OK": ""
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"id" : "fooid",
"args" : {
"action" : "startjail",
"jail" : "test"
},
"name" : "iocage"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"startjail": {
"test": {
"INFO": " 0bf985de-ca0f-11e5-8d45-d05099728dbf (test) is already up"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: stopjail, iocage
.. _Stop a Jail:
Stop a Jail
===========
The "stopjail" action stops the specified jail.
.. note:: since a jail can only be stopped once, you will receive an error if the jail is not running.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "stopjail",
"jail" : "test"
}
**REST Response**
.. code-block:: json
{
"args": {
"stopjail": {
"test": {
"* Stopping 0bf985de-ca0f-11e5-8d45-d05099728dbf (test)": "",
"+ Removing jail process OK": "",
"+ Running post-stop OK": "",
"+ Running pre-stop OK": "",
"+ Stopping services OK": ""
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"jail" : "test",
"action" : "stopjail"
},
"namespace" : "sysadm",
"id" : "fooid",
"name" : "iocage"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"stopjail": {
"test": {
"INFO": " 0bf985de-ca0f-11e5-8d45-d05099728dbf (test) is already down"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: capjail, iocage
.. _Cap a Jail:
Cap a Jail
===========
The "capjail" action re-applies resource limits to a running jail. Use this action when you make a change to the specified jail's resources and want to apply the changes without restarting
the jail.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"jail" : "test",
"action" : "capjail"
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"jail" : "test",
"action" : "capjail"
},
"namespace" : "sysadm",
"name" : "iocage",
"id" : "fooid"
}
**Response**
.. code-block:: json
{
"args": {
"capjail": {
"success": "jail test capped."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: cleanjails, iocage
.. _Clean Jails:
Clean Jails
===========
The "cleanjails" action destroys all existing jail datasets, including all data stored in the jails.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "cleanjails"
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"args" : {
"action" : "cleanjails"
},
"id" : "fooid",
"name" : "iocage"
}
**Response**
.. code-block:: json
{
"args": {
"cleanjails": {
"success": "All jails have been cleaned."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: cleanreleases, iocage
.. _Clean Releases:
Clean Releases
==============
The "cleanreleases" action deletes all releases that have been fetched. Since basejails rely on releases, do not run this action if any basejails still exist.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "cleanreleases"
}
**WebSocket Request**
**REST Request**
.. code-block:: json
{
"id" : "fooid",
"namespace" : "sysadm",
"args" : {
"action" : "cleanreleases"
},
"name" : "iocage"
}
**Response**
**REST Request**
.. code-block:: json
{
"args": {
"cleanreleases": {
"success": "All RELEASEs have been cleaned."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: cleantemplates, iocage
.. _Clean Templates:
Clean Templates
===============
The "cleantemplates" action destroys all existing jail templates.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "cleantemplates"
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"action" : "cleantemplates"
},
"name" : "iocage",
"id" : "fooid",
"namespace" : "sysadm"
}
**Response**
.. code-block:: json
{
"args": {
"cleantemplates": {
"success": "All templates have been cleaned."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: cleanall, iocage
.. _Clean All:
Clean All
===========
The "cleanall" action destroys everything associated with iocage.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "cleanall"
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"args" : {
"action" : "cleanall"
},
"id" : "fooid",
"name" : "iocage"
}
**Response**
.. code-block:: json
{
"args": {
"cleanall": {
"success": "All iocage datasets have been cleaned."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: activatepool, iocage
.. _Activate a Pool:
Activate a Pool
===============
The "activatepool" action can be used to specify which ZFS pool is used to store jails. If you do not specify the pool, the response will indicate the current setting.
These examples specify the pool to use:
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "activatepool",
"pool" : "tank"
}
**REST Response**
.. code-block:: json
{
"args": {
"activatepool": {
"success": "pool tank activated."
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"action" : "activatepool",
"pool" : "tank"
},
"name" : "iocage",
"id" : "fooid",
"namespace" : "sysadm"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"activatepool": {
"success": "pool tank activated."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
These examples show responses when the pool is not specified:
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "activatepool"
}
**REST Response**
.. code-block:: json
{
"args": {
"activatepool": {
"currently active": {
"pool": " tank"
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"action" : "activatepool"
},
"namespace" : "sysadm",
"name" : "iocage",
"id" : "fooid"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"activatepool": {
"currently active": {
"pool": " tank"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: deactivatepool, iocage
.. _Deactivate a Pool:
Deactivate a Pool
=================
Since only one pool can be active, the "deactivatepool" action can be used to deactivate a currently active pool. This should be done before using the
"activatepool" action to activate a different pool. When a pool is deactivated, no data is removed. However, you won't have access to its jails unless you move those datasets to the newly
activated pool or activate the old pool again.
**REST Request**
.. code-block:: json
PUT /sysadm/iocage
{
"action" : "deactivatepool",
"pool" : "tank"
}
**REST Response**
.. code-block:: json
{
"args": {
"deactivatepool": {
"success": "pool tank deactivated."
}
}
}
**WebSocket Request**
.. code-block:: json
{
"id" : "fooid",
"name" : "iocage",
"args" : {
"pool" : "tank",
"action" : "deactivatepool"
},
"namespace" : "sysadm"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"deactivatepool": {
"success": "pool tank deactivated."
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}

247
api/classes/iohyve.rst Normal file
View File

@@ -0,0 +1,247 @@
.. _iohyve:
iohyve
******
The iohyve class is used to manage virtual machines (VMs) running in the bhyve type 2 hypervisor.
Every iohyve class request contains the following parameters:
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| **Parameter** | **Value** | **Description** |
| | | |
+=================================+===============+======================================================================================================================+
| id | | any unique value for the request; examples include a hash, checksum, or uuid |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| name | iohyve | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| namespace | sysadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| action | | supported actions include "listvms", "fetchiso", "renameiso", "rmiso" |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
The rest of this section provides examples of the available *actions* for each type of request, along with their responses.
.. index:: listvms, iohyve
.. _List VMs:
List VMs
========
The "listvms" action lists information about currently installed VMs. For each VM, the response includes the VM's name, description, whether or not it is scheduled to start when the host
system boots, whether or not it is currently running, and whether or not the VM is currently loaded into memory.
**REST Request**
.. code-block:: json
PUT /sysadm/iohyve
{
"action" : "listvms"
}
**REST Response**
.. code-block:: json
{
"args": {
"listvms": {
"testguest": {
"description": "February 1, 2016 at 03:11:57 PM EST",
"rcboot": "NO",
"running": "NO",
"vmm": "YES"
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"args" : {
"action" : "listvms"
},
"name" : "iohyve",
"id" : "fooid"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"listvms": {
"testguest": {
"description": "February 1, 2016 at 03:11:57 PM EST",
"rcboot": "NO",
"running": "NO",
"vmm": "YES"
}
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: fetchiso, iohyve
.. _Fetch ISO:
Fetch ISO
=========
The "fetchiso" action is used to retrieve the installation ISO. It is used with the "url" argument which contains the ISO address beginning with *http://*,
*ftp://*, or
*file://*.
**REST Request**
.. code-block:: json
PUT /sysadm/iohyve
{
"url" : "ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/10.1/FreeBSD-10.1-RELEASE-amd64-disc1.iso",
"action" : "fetchiso"
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"name" : "iohyve",
"args" : {
"url" : "ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/10.1/FreeBSD-10.1-RELEASE-amd64-disc1.iso",
"action" : "fetchiso"
},
"id" : "fooid"
}
**Response**
.. code-block:: json
{
"args": {
"fetchiso": {
"command": "iohyve fetch ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/amd64/ISO-IMAGES/10.1/FreeBSD-10.1-RELEASE-amd64-disc1.iso",
"comment": "Task Queued",
"queueid": "{b3a8b980-a564-4ff8-86a2-1971bd4f58d1}"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: renameiso, iohyve
.. _Rename ISO:
Rename ISO
==========
The "renameiso" action is used to to rename an existing ISO file on disk. Specify the existing name with "source" and the new name with "target".
**REST Request**
.. code-block:: json
PUT /sysadm/iohyve
{
"source" : "test.iso",
"target" : "102.iso",
"action" : "renameiso"
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"target" : "102.iso",
"source" : "test.iso",
"action" : "renameiso"
},
"id" : "fooid",
"name" : "iohyve",
"namespace" : "sysadm"
}
**Response**
.. code-block:: json
{
"args": {
"renameiso": {
"source": "test.iso",
"target": "102.iso"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: rmiso, iohyve
.. _Remove ISO:
Remove ISO
==========
The "rmiso" action is used to to remove an existing ISO file from disk. Specify the ISO's name as the "target".
**REST Request**
.. code-block:: json
PUT /sysadm/iohyve
{
"action" : "rmiso",
"target" : "FreeBSD-10.2-RELEASE-amd64-bootonly.iso"
}
**WebSocket Request**
.. code-block:: json
{
"id" : "fooid",
"name" : "iohyve",
"args" : {
"target" : "FreeBSD-10.2-RELEASE-amd64-bootonly.iso",
"action" : "rmiso"
},
"namespace" : "sysadm"
}
**Response**
.. code-block:: json
{
"args": {
"rmiso": {
"target": "FreeBSD-10.2-RELEASE-amd64-bootonly.iso"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}

View File

@@ -1,9 +1,9 @@
.. _systemmanager:
systemmanager
**********
*************
The systemmanager class is used to manage various aspects of the FreeBSD system. Every systemmanager class request contains the following parameters:
The systemmanager class is used to retrieve information about the system. Every systemmanager class request contains the following parameters:
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| **Parameter** | **Value** | **Description** |
@@ -18,7 +18,8 @@ The systemmanager class is used to manage various aspects of the FreeBSD system.
| namespace | sysadm | |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
| action | | supported actions include "memorystats", "cpupercentage", "cputemps", "batteryinfo", "externalmounts", "systemmanager" |
| action | | supported actions include "memorystats", "cpupercentage", "cputemps", "procinfo", "killproc", "batteryinfo", |
| | | "externalmounts", "systemmanager", "sysctllist", and "setsysctl" |
| | | |
+---------------------------------+---------------+----------------------------------------------------------------------------------------------------------------------+
@@ -236,6 +237,154 @@ The "cputemps" action returns the temperature of each CPU.
"namespace": "sysadm"
}
.. index:: procinfo, systemmanager
.. _Process Information:
Process Information
===================
The "procinfo" action lists information about each running process. Since a system will have many running processes, the responses in this section only show one process as an example
of the type of information listed by this action.
**REST Request**
.. code-block:: json
PUT /sysadm/systemmanager
{
"action" : "procinfo"
}
**REST Response**
.. code-block:: json
{
"args": {
"procinfo": {
"228": {
"command": "adjkerntz",
"cpu": "3",
"nice": "0",
"pri": "52",
"res": "1968K",
"size": "8276K",
"state": "pause",
"thr": "1",
"time": "0:00",
"username": "root",
"wcpu": "0.00%"
}
}
}
}
**WebSocket Request**
.. code-block:: json
{
"id" : "fooid",
"namespace" : "sysadm",
"name" : "systemmanager",
"args" : {
"action" : "procinfo"
}
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"procinfo": {
"228": {
"command": "adjkerntz",
"cpu": "3",
"nice": "0",
"pri": "52",
"res": "1968K",
"size": "8276K",
"state": "pause",
"thr": "1",
"time": "0:00",
"username": "root",
"wcpu": "0.00%"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: killproc, systemmanager
.. _Kill a Process:
Kill a Process
==============
The "killproc" action can be used to send the specified signal to the specified Process ID (PID). The following signals are supported: INT, QUIT, ABRT, KILL, ALRM, or TERM.
**REST Request**
.. code-block:: json
PUT /sysadm/systemmanager
{
"signal" : "KILL",
"pid" : "13939",
"action" : "killproc"
}
**REST Response**
.. code-block:: json
{
"args": {
"killproc": {
"action": "killproc",
"pid": "13939",
"signal": "KILL"
}
}
}
**WebSocket Request**
.. code-block:: json
{
"namespace" : "sysadm",
"args" : {
"pid" : "13939",
"action" : "killproc",
"signal" : "KILL"
},
"id" : "fooid",
"name" : "systemmanager"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"killproc": {
"action": "killproc",
"pid": "13939",
"signal": "KILL"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: batteryinfo, systemmanager
.. _Battery Information:
@@ -436,3 +585,143 @@ of RAM, and the system's uptime.
"name": "response",
"namespace": "sysadm"
}
.. index:: sysctllist, systemmanager
.. _List Sysctls:
List Sysctls
============
The "sysctllist" action lists returns the list of all setable sysctl values. Since there are many, the example responses in this section have been truncated to just show a few.
**REST Request**
.. code-block:: json
PUT /sysadm/systemmanager
{
"action" : "sysctllist"
}
**REST Response**
.. code-block:: json
{
"args": {
"sysctllist": {
"compat.ia32.maxdsiz": "536870912",
"compat.ia32.maxssiz": "67108864",
"compat.ia32.maxvmem": "0",
"compat.linux.osname": "Linux",
"compat.linux.osrelease": "2.6.18",
"compat.linux.oss_version": "198144",
"compat.linux32.maxdsiz": "536870912",
"compat.linux32.maxssiz": "67108864",
"compat.linux32.maxvmem": "0",
}
}
}
**WebSocket Request**
.. code-block:: json
{
"name" : "systemmanager",
"namespace" : "sysadm",
"id" : "fooid",
"args" : {
"action" : "sysctllist"
}
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"sysctllist": {
"compat.ia32.maxdsiz": "536870912",
"compat.ia32.maxssiz": "67108864",
"compat.ia32.maxvmem": "0",
"compat.linux.osname": "Linux",
"compat.linux.osrelease": "2.6.18",
"compat.linux.oss_version": "198144",
"compat.linux32.maxdsiz": "536870912",
"compat.linux32.maxssiz": "67108864",
"compat.linux32.maxvmem": "0",
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}
.. index:: setsysctl, systemmanager
.. _Set a Sysctl:
Set a Sysctl
============
The "setsysctl" action sets the specified setable sysctl to the specified value. The response indicates that the old value was changed to the new value.
**REST Request**
.. code-block:: json
PUT /sysadm/systemmanager
{
"value" : "0",
"sysctl" : "security.jail.mount_devfs_allowed",
"action" : "setsysctl"
}
**REST Response**
.. code-block:: json
{
"args": {
"setsysctl": {
"response": "security.jail.mount_devfs_allowed: 1 -> 0",
"sysctl": "security.jail.mount_devfs_allowed",
"value": "0"
}
}
}
**WebSocket Request**
.. code-block:: json
{
"args" : {
"value" : "0",
"action" : "setsysctl",
"sysctl" : "security.jail.mount_devfs_allowed"
},
"name" : "systemmanager",
"namespace" : "sysadm",
"id" : "fooid"
}
**WebSocket Response**
.. code-block:: json
{
"args": {
"setsysctl": {
"response": "security.jail.mount_devfs_allowed: 1 -> 0",
"sysctl": "security.jail.mount_devfs_allowed",
"value": "0"
}
},
"id": "fooid",
"name": "response",
"namespace": "sysadm"
}

View File

@@ -162,7 +162,7 @@ The "startupdate" action starts the specified update. You must specify a "target
* **fbsdupdatepkgs:** update installed software and apply FreeBSD system updates.
* **standalone:** only update package specified as a "tag" (e.g. pkgng-1.6.9).
* **standalone:** only apply the update specified as a "tag". Use the "checkupdates" action to determine the name (tag) of the update to specify.
**REST Request**

View File

@@ -1,4 +1,4 @@
// ===============================
// ===============================
// PC-BSD REST API Server
// Available under the 3-clause BSD License
// Written by: Ken Moore <ken@pcbsd.org> DEC 2015
@@ -9,6 +9,7 @@
#include <WebSocket.h>
//sysadm library interface classes
#include "library/sysadm-beadm.h"
#include "library/sysadm-general.h"
#include "library/sysadm-iocage.h"
#include "library/sysadm-iohyve.h"
@@ -36,6 +37,12 @@ RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(bool allaccess, QJsonO
out->insert("rpc/syscache","read"); //no write to syscache - only reads
}
// - beadm
if(QFile::exists("/usr/local/sbin/beadm")){
out->insert("sysadm/beadm", "read/write");
}
// - dispatcher (Internal to server - always available)
//"read" is the event notifications, "write" is the ability to queue up jobs
out->insert("rpc/dispatcher", allaccess ? "read/write" : "read");
@@ -90,6 +97,8 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(const RestInputStru
//Go through and forward this request to the appropriate sub-system
if(namesp=="rpc" && name=="dispatcher"){
return EvaluateDispatcherRequest(IN.fullaccess, IN.args, out);
}else if(namesp=="sysadm" && name=="beadm"){
return EvaluateSysadmBEADMRequest(IN.args, out);
}else if(namesp=="sysadm" && name=="iocage"){
return EvaluateSysadmIocageRequest(IN.args, out);
}else if(namesp=="sysadm" && name=="iohyve"){
@@ -182,6 +191,33 @@ RestOutputStruct::ExitCode WebSocket::EvaluateDispatcherRequest(bool allaccess,
return RestOutputStruct::OK;
}
//==== SYSADM -- BEADM ====
RestOutputStruct::ExitCode WebSocket::EvaluateSysadmBEADMRequest(const QJsonValue in_args, QJsonObject *out){
if(in_args.isObject()){
QStringList keys = in_args.toObject().keys();
bool ok = false;
if(keys.contains("action")){
QString act = JsonValueToString(in_args.toObject().value("action"));
if(act=="listbes"){
ok = true;
out->insert("listbes", sysadm::BEADM::listBEs());
}
if(act=="renamebe"){
ok = true;
out->insert("renamebe", sysadm::BEADM::renameBE(in_args.toObject()));
}
} //end of "action" key usage
//If nothing done - return the proper code
if(!ok){
return RestOutputStruct::BADREQUEST;
}
}else{ // if(in_args.isArray()){
return RestOutputStruct::BADREQUEST;
}
return RestOutputStruct::OK;
}
//==== SYSADM -- Network ====
RestOutputStruct::ExitCode WebSocket::EvaluateSysadmNetworkRequest(const QJsonValue in_args, QJsonObject *out){
if(in_args.isObject()){
@@ -389,6 +425,26 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIocageRequest(const QJsonVal
bool ok = false;
if(keys.contains("action")){
QString act = JsonValueToString(in_args.toObject().value("action"));
if(act=="cleanall"){
ok = true;
out->insert("cleanall", sysadm::Iocage::cleanAll());
}
if(act=="cleantemplates"){
ok = true;
out->insert("cleantemplates", sysadm::Iocage::cleanTemplates());
}
if(act=="cleanreleases"){
ok = true;
out->insert("cleanreleases", sysadm::Iocage::cleanReleases());
}
if(act=="cleanjails"){
ok = true;
out->insert("cleanjails", sysadm::Iocage::cleanJails());
}
if(act=="capjail"){
ok = true;
out->insert("capjail", sysadm::Iocage::capJail(in_args.toObject()));
}
if(act=="deactivatepool"){
ok = true;
out->insert("deactivatepool", sysadm::Iocage::deactivatePool(in_args.toObject()));
@@ -441,7 +497,18 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIohyveRequest(const QJsonVal
ok = true;
out->insert("listvms", sysadm::Iohyve::listVMs());
}
if(act=="fetchiso"){
ok = true;
out->insert("fetchiso", sysadm::Iohyve::fetchISO(in_args.toObject()));
}
if(act=="renameiso"){
ok = true;
out->insert("renameiso", sysadm::Iohyve::renameISO(in_args.toObject()));
}
if(act=="rmiso"){
ok = true;
out->insert("rmiso", sysadm::Iohyve::rmISO(in_args.toObject()));
}
} //end of "action" key usage
//If nothing done - return the proper code

View File

@@ -46,6 +46,8 @@ private:
// -- Individual subsystems
RestOutputStruct::ExitCode EvaluateSyscacheRequest(const QJsonValue in_args, QJsonObject *out);
RestOutputStruct::ExitCode EvaluateDispatcherRequest(bool allaccess, const QJsonValue in_args, QJsonObject *out);
// -- sysadm beadm API
RestOutputStruct::ExitCode EvaluateSysadmBEADMRequest(const QJsonValue in_args, QJsonObject *out);
// -- sysadm iocage API
RestOutputStruct::ExitCode EvaluateSysadmIocageRequest(const QJsonValue in_args, QJsonObject *out);
// -- sysadm iohyve API

View File

@@ -3,6 +3,7 @@ CONFIG += c++11
HEADERS += $${PWD}/sysadm-global.h \
$${PWD}/sysadm-general.h \
$${PWD}/sysadm-beadm.h \
$${PWD}/sysadm-iocage.h \
$${PWD}/sysadm-iohyve.h \
$${PWD}/sysadm-lifepreserver.h \
@@ -15,6 +16,7 @@ HEADERS += $${PWD}/sysadm-global.h \
SOURCES += $${PWD}/NetDevice.cpp \
$${PWD}/sysadm-general.cpp \
$${PWD}/sysadm-beadm.cpp \
$${PWD}/sysadm-iocage.cpp \
$${PWD}/sysadm-iohyve.cpp \
$${PWD}/sysadm-lifepreserver.cpp \

View File

@@ -0,0 +1,77 @@
//===========================================
// PC-BSD source code
// Copyright (c) 2015, PC-BSD Software/iXsystems
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
#include <QUuid>
#include "sysadm-general.h"
#include "sysadm-beadm.h"
#include "sysadm-global.h"
#include "globals.h"
using namespace sysadm;
//PLEASE: Keep the functions in the same order as listed in pcbsd-general.h
// List all the available BEs
QJsonObject BEADM::listBEs() {
QJsonObject retObject;
QStringList output = General::RunCommand("beadm list -H").split("\n");
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).isEmpty() )
break;
QString line = output.at(i).simplified();
QString beName = line.section(" ", 0, 0);
QString beActive = line.section(" ", 1, 1);
QString beMount = line.section(" ", 2, 2);
QString beSpace = line.section(" ", 3, 3);
QString beDate = line.section(" ", 4, 4);
QString beNick = line.section(" ", 5, 5);
QJsonObject vals;
vals.insert("active", beActive);
vals.insert("mount", beMount);
vals.insert("space", beSpace);
vals.insert("date", beDate);
vals.insert("nick", beNick);
retObject.insert(beName, vals);
}
return retObject;
}
QJsonObject BEADM::renameBE(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("source") || ! keys.contains("target") ) {
retObject.insert("error", "Missing required key(s) 'source / target'");
return retObject;
}
// Get the key values
QString source = jsin.value("source").toString();
QString target = jsin.value("target").toString();
QStringList output = General::RunCommand("beadm rename " + source + " " + target).split("\n");
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).indexOf("ERROR") != -1 ) {
retObject.insert("error", output.at(i));
return retObject;
}
}
retObject.insert("source", source);
retObject.insert("target", target);
return retObject;
}

View File

@@ -0,0 +1,23 @@
//===========================================
// PC-BSD source code
// Copyright (c) 2015, PC-BSD Software/iXsystems
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
#ifndef __PCBSD_LIB_UTILS_BEADM_H
#define __PCBSD_LIB_UTILS_BEADM_H
#include <QJsonObject>
#include "sysadm-global.h"
namespace sysadm{
class BEADM{
public:
static QJsonObject listBEs();
static QJsonObject renameBE(QJsonObject);
};
} //end of pcbsd namespace
#endif

View File

@@ -12,6 +12,126 @@ using namespace sysadm;
//PLEASE: Keep the functions in the same order as listed in pcbsd-general.h
// Clean everything iocage related on a box
QJsonObject Iocage::cleanAll() {
QJsonObject retObject;
QStringList output = General::RunCommand("iocage clean -fa ").split("\n");
for ( int i = 0; i < output.size(); i++)
{
// This means either a mount is stuck or a jail cannot be stopped,
// give them the error.
if ( output.at(i).indexOf("ERROR:") != -1 ) {
retObject.insert("error", output.at(i));
break;
} else {
// iocage does a spinner for these that is distracting to see returned,
// returning what a user wants to actually see.
retObject.insert("success", "All iocage datasets have been cleaned.");
}
}
return retObject;
}
// Clean all templates on a box
QJsonObject Iocage::cleanTemplates() {
QJsonObject retObject;
QStringList output = General::RunCommand("iocage clean -ft ").split("\n");
for ( int i = 0; i < output.size(); i++)
{
// This means either a mount is stuck or a jail cannot be stopped,
// give them the error.
if ( output.at(i).indexOf("ERROR:") != -1 ) {
retObject.insert("error", output.at(i));
break;
} else {
// iocage does a spinner for these that is distracting to see returned,
// returning what a user wants to actually see.
retObject.insert("success", "All templates have been cleaned.");
}
}
return retObject;
}
// Clean all RELEASEs on a box
QJsonObject Iocage::cleanReleases() {
QJsonObject retObject;
QStringList output = General::RunCommand("iocage clean -fr ").split("\n");
for ( int i = 0; i < output.size(); i++)
{
// This means either a mount is stuck or a jail cannot be stopped,
// give them the error.
if ( output.at(i).indexOf("ERROR:") != -1 ) {
retObject.insert("error", output.at(i));
break;
} else {
// iocage does a spinner for these that is distracting to see returned,
// returning what a user wants to actually see.
retObject.insert("success", "All RELEASEs have been cleaned.");
}
}
return retObject;
}
// Clean all jails on a box
QJsonObject Iocage::cleanJails() {
QJsonObject retObject;
QStringList output = General::RunCommand("iocage clean -fj ").split("\n");
for ( int i = 0; i < output.size(); i++)
{
// This means either a mount is stuck or a jail cannot be stopped,
// give them the error.
if ( output.at(i).indexOf("ERROR:") != -1 ) {
retObject.insert("error", output.at(i));
break;
} else {
// iocage does a spinner for these that is distracting to see returned,
// returning what a user wants to actually see.
retObject.insert("success", "All jails have been cleaned.");
}
}
return retObject;
}
// Resource cap a jail on the box
QJsonObject Iocage::capJail(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("jail") ) {
retObject.insert("error", "Missing required keys");
return retObject;
}
// Get the key values
QString jail = jsin.value("jail").toString();
QStringList output = General::RunCommand("iocage cap " + jail).split("\n");
QJsonObject vals;
for ( int i = 0; i < output.size(); i++)
{
if ( ! output.at(i).isEmpty())
break;
// When a cap is successful, iocage doesn't return anything, so we have to
// fudge the output a bit.
retObject.insert("success", "jail " + jail + " capped.");
}
return retObject;
}
// Deactivate a zpool for iocage on the box
QJsonObject Iocage::deactivatePool(QJsonObject jsin) {
QJsonObject retObject;

View File

@@ -14,6 +14,11 @@ namespace sysadm{
class Iocage{
public:
static QJsonObject cleanAll();
static QJsonObject cleanTemplates();
static QJsonObject cleanReleases();
static QJsonObject cleanJails();
static QJsonObject capJail(QJsonObject);
static QJsonObject deactivatePool(QJsonObject);
static QJsonObject activatePool(QJsonObject);
static QJsonObject stopJail(QJsonObject);

View File

@@ -4,14 +4,43 @@
// Available under the 3-clause BSD license
// See the LICENSE file for full details
//===========================================
#include <QUuid>
#include "sysadm-general.h"
#include "sysadm-iohyve.h"
#include "sysadm-global.h"
#include "globals.h"
using namespace sysadm;
//PLEASE: Keep the functions in the same order as listed in pcbsd-general.h
// Queue the fetch of an ISO
QJsonObject Iohyve::fetchISO(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("url") ) {
retObject.insert("error", "Missing required key 'url'");
return retObject;
}
// Get the key values
QString url = jsin.value("url").toString();
// Create a unique ID for this queued action
QString ID = QUuid::createUuid().toString();
// Queue the fetch action
DISPATCHER->queueProcess(ID, "iohyve fetch " + url);
// Return some details to user that the action was queued
retObject.insert("command", "iohyve fetch " + url);
retObject.insert("comment", "Task Queued");
retObject.insert("queueid", ID);
return retObject;
}
// List the VMs on the box
QJsonObject Iohyve::listVMs() {
QJsonObject retObject;
@@ -40,3 +69,57 @@ QJsonObject Iohyve::listVMs() {
return retObject;
}
// Rename an ISO file
QJsonObject Iohyve::renameISO(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("source") || ! keys.contains("target") ) {
retObject.insert("error", "Missing required key(s) 'source / target'");
return retObject;
}
// Get the key values
QString source = jsin.value("source").toString();
QString target = jsin.value("target").toString();
QStringList output = General::RunCommand("iohyve renameiso " + source + " " + target).split("\n");
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).indexOf("cannot open") != -1 ) {
retObject.insert("error", output.at(i));
return retObject;
}
}
retObject.insert("source", source);
retObject.insert("target", target);
return retObject;
}
// Remove an ISO file
QJsonObject Iohyve::rmISO(QJsonObject jsin) {
QJsonObject retObject;
QStringList keys = jsin.keys();
if (! keys.contains("target") ) {
retObject.insert("error", "Missing required key 'target'");
return retObject;
}
// Get the key values
QString target = jsin.value("target").toString();
QStringList output = General::RunCommand("iohyve rmiso " + target).split("\n");
for ( int i = 0; i < output.size(); i++)
{
if ( output.at(i).indexOf("cannot open") != -1 ) {
retObject.insert("error", output.at(i));
return retObject;
}
}
retObject.insert("target", target);
return retObject;
}

View File

@@ -14,7 +14,10 @@ namespace sysadm{
class Iohyve{
public:
static QJsonObject fetchISO(QJsonObject);
static QJsonObject listVMs();
static QJsonObject renameISO(QJsonObject);
static QJsonObject rmISO(QJsonObject);
};
} //end of pcbsd namespace

View File

@@ -127,7 +127,7 @@ QJsonObject LifePreserver::initReplication(QJsonObject jsin) {
QJsonObject LifePreserver::listCron() {
QJsonObject retObject;
QStringList output = General::RunCommand("lpreserver listcron").split("\n");
QStringList output = General::RunCommand("lpreserver cronsnap list").split("\n");
QList<QStringList> snaps;
// Parse the output
@@ -254,7 +254,7 @@ QJsonObject LifePreserver::listSnap(QJsonObject jsin) {
return retObject;
}
QStringList output = General::RunCommand("lpreserver listsnap " + pool ).split("\n");
QStringList output = General::RunCommand("lpreserver snapshot list " + pool ).split("\n");
QList<QStringList> snaps;
QStringList snapitems;
QRegExp sep("\\s+");
@@ -350,7 +350,7 @@ QJsonObject LifePreserver::removeSnapshot(QJsonObject jsin) {
}
QStringList output;
output = General::RunCommand("lpreserver rmsnap " + dataset + " " + snap).split("\n");
output = General::RunCommand("lpreserver snapshot remove " + dataset + " " + snap).split("\n");
// Check for any errors
for ( int i = 0; i < output.size(); i++)
@@ -426,7 +426,7 @@ QJsonObject LifePreserver::revertSnapshot(QJsonObject jsin) {
}
QStringList output;
output = General::RunCommand("lpreserver revertsnap " + dataset + " " + snap).split("\n");
output = General::RunCommand("lpreserver snapshot revert " + dataset + " " + snap).split("\n");
// Check for any errors
for ( int i = 0; i < output.size(); i++)
@@ -589,9 +589,9 @@ QJsonObject LifePreserver::scheduleSnapshot(QJsonObject jsin) {
QStringList output;
if ( frequency == "none" )
output = General::RunCommand("lpreserver cronsnap " + pool + " stop " ).split("\n");
output = General::RunCommand("lpreserver cronsnap stop " + pool ).split("\n");
else
output = General::RunCommand("lpreserver cronsnap " + pool + " start " + frequency + " " + keep ).split("\n");
output = General::RunCommand("lpreserver cronsnap start " + pool + " " + frequency + " " + keep ).split("\n");
// Check for any errors
for ( int i = 0; i < output.size(); i++)

View File

@@ -2,12 +2,30 @@
# (Yes, yes, this is a bash script)
# Both resty/jsawk use bash'isms
# Possible environment variables
# APITESTUSER - username
# APITESTPASS - password
# APITESTNAMESPACE - namespace / sysadm
# APITESTCLASS - API class
# APITESTPAYLOAD - JSON payload
# Default values
DEFUSER="root"
DEFNAMESPACE="sysadm"
DEFCLASS="lifepreserver"
# Set variable to call jsawk utility
JSAWK="./utils/jsawk -j js24"
if [ `id -u` != "0" ] ; then
pkgPre="sudo"
else
pkgPre=""
fi
which npm >/dev/null 2>/dev/null
if [ $? -ne 0 ] ; then
pkg install -y npm
$pkgPre pkg install -y npm
if [ $? -ne 0 ] ; then
echo "Requires npm!"
exit 1
@@ -16,7 +34,7 @@ fi
pkg info p5-JSON >/dev/null 2>/dev/null
if [ $? -ne 0 ] ; then
pkg install -y p5-JSON
$pkgPre pkg install -y p5-JSON
if [ $? -ne 0 ] ; then
echo "Requires p5-JSON!"
exit 1
@@ -39,75 +57,96 @@ if [ ! -d "${HOME}/.npm/wss" ] ; then
fi
fi
echo "Enter your username:"
echo -e ">\c"
read fuser
echo ""
echo "Enter your password:"
echo -e ">\c"
read -s fpass
echo ""
echo "Enter the namespace:"
echo -e "(sysadm)>\c"
read namesp
if [ -z "$namesp" ] ; then
namesp="sysadm"
if [ -z "$APITESTUSER" ] ; then
echo "Enter your username:"
echo -e "($DEFUSER)>\c"
read APITESTUSER
if [ -z "$APITESTUSER" ] ; then
APITESTUSER="$DEFUSER"
fi
echo ""
fi
echo ""
echo "Enter the class name:"
echo -e "(lifepreserver)>\c"
read name
if [ -z "$name" ] ; then
name="lifepreserver"
if [ -z "$APITESTPASS" ] ; then
echo "Enter your password:"
echo -e ">\c"
read -s APITESTPASS
echo ""
fi
echo ""
echo "Enter the payload json:"
echo -e "{ \"action\":\"listcron\" }>\c"
read payload
if [ -z "$payload" ] ; then
payload="{ \"action\":\"listcron\" }"
if [ -z "$APITESTNAMESPACE" ] ; then
echo "Enter the namespace:"
echo -e "($DEFNAMESPACE)>\c"
read APITESTNAMESPACE
if [ -z "$APITESTNAMESPACE" ] ; then
APITESTNAMESPACE="$DEFNAMESPACE"
fi
echo ""
fi
if [ -z "$APITESTCLASS" ] ; then
echo "Enter the class name:"
echo -e "($DEFCLASS)>\c"
read APITESTCLASS
if [ -z "$APITESTCLASS" ] ; then
APITESTCLASS="$DEFCLASS"
fi
echo ""
fi
if [ -z "$APITESTPAYLOAD" ] ; then
echo "Enter the payload json:"
echo -e "{ \"action\":\"listcron\" }>\c"
read APITESTPAYLOAD
if [ -z "$APITESTPAYLOAD" ] ; then
APITESTPAYLOAD="{ \"action\":\"listcron\" }"
fi
echo ""
fi
echo ""
# Source our resty functions
. ./utils/resty -W "https://127.0.0.1:12151" -H "Accept: application/json" -H "Content-Type: application/json" -u ${fuser}:${fpass}
#. ./utils/resty -W "https://127.0.0.1:12151" -H "Accept: application/json" -H "Content-Type: application/json" -u ${fuser}:${fpass}
# Save output to a file in addition to stdout
ofile="/tmp/api-response"
echo "" > /tmp/api-response
#ofile="/tmp/api-response"
#echo "" > /tmp/api-response
# Check the reply of this REST query
echo "" | tee -a $ofile
echo "REST Request:" | tee -a $ofile
echo "-------------------------------" | tee -a $ofile
echo "PUT /${namesp}/${name}" | tee -a $ofile
echo "${payload}" | perl -0007 -MJSON -ne'print to_json(from_json($_, {allow_nonref=>1}),{pretty=>1})."\n"' | tee -a $ofile
#echo "" | tee -a $ofile
#echo "REST Request:" | tee -a $ofile
#echo "-------------------------------" | tee -a $ofile
#echo "PUT /${namesp}/${name}" | tee -a $ofile
#echo "${payload}" | perl -0007 -MJSON -ne'print to_json(from_json($_, {allow_nonref=>1}),{pretty=>1})."\n"' | tee -a $ofile
echo "" | tee -a $ofile
echo "REST Response:" | tee -a $ofile
echo "-------------------------------" | tee -a $ofile
PUT /${namesp}/${name} "${payload}" -v -k 2>/tmp/.rstErr | tee -a $ofile
if [ $? -ne 0 ] ; then
echo "Failed.. Error output:"
cat /tmp/.rstErr
fi
rm $ofile
rm /tmp/.rstErr
#echo "" | tee -a $ofile
#echo "REST Response:" | tee -a $ofile
#echo "-------------------------------" | tee -a $ofile
#PUT /${namesp}/${name} "${payload}" -v -k 2>/tmp/.rstErr | tee -a $ofile
#if [ $? -ne 0 ] ; then
# echo "Failed.. Error output:"
# cat /tmp/.rstErr
#fi
#rm $ofile
#rm /tmp/.rstErr
# Now check the response via WebSockets
export NODE_TLS_REJECT_UNAUTHORIZED=0
rm $ofile >/dev/null 2>/dev/null
ofile="/tmp/api-response"
echo "" > $ofile
echo "REST Request:" | tee -a $ofile
echo "-------------------------------" | tee -a $ofile
echo "PUT /${APITESTNAMESPACE}/${APITESTCLASS}" | tee -a $ofile
echo "${APITESTPAYLOAD}" | perl -0007 -MJSON -ne'print to_json(from_json($_, {allow_nonref=>1}),{pretty=>1})."\n"' | tee -a $ofile
echo "" | tee -a $ofile
echo "WebSocket Request:" | tee -a $ofile
echo "-------------------------------" | tee -a $ofile
echo "{ \"namespace\":\"${namesp}\", \"name\":\"${name}\", \"id\":\"fooid\", \"args\":${payload} }" | perl -0007 -MJSON -ne'print to_json(from_json($_, {allow_nonref=>1}),{pretty=>1})."\n"' | tee -a $ofile
echo "{ \"namespace\":\"${APITESTNAMESPACE}\", \"name\":\"${APITESTCLASS}\", \"id\":\"fooid\", \"args\":${APITESTPAYLOAD} }" | perl -0007 -MJSON -ne'print to_json(from_json($_, {allow_nonref=>1}),{pretty=>1})."\n"' | tee -a $ofile
echo "" | tee -a $ofile
echo "WebSocket Response:" | tee -a $ofile
echo "Response:" | tee -a $ofile
echo "-------------------------------" | tee -a $ofile
echo "{ \"namespace\":\"${namesp}\", \"name\":\"${name}\", \"id\":\"fooid\", \"args\":${payload} }" | node sendwebsocket.js "$fuser" "$fpass" | tee -a $ofile
rm $ofile
echo "{ \"namespace\":\"${APITESTNAMESPACE}\", \"name\":\"${APITESTCLASS}\", \"id\":\"fooid\", \"args\":${APITESTPAYLOAD} }" | node sendwebsocket.js "$APITESTUSER" "$APITESTPASS" | tee -a $ofile