Skip to content

Commit

Permalink
Merge pull request #37 from maerteijn/nightmarejs
Browse files Browse the repository at this point in the history
Added functional and unit tests
  • Loading branch information
Martijn Jacobs authored Aug 19, 2018
2 parents 6584b39 + 2bb18db commit f81c06f
Show file tree
Hide file tree
Showing 19 changed files with 1,860 additions and 71 deletions.
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
language: node_js

node_js:
- "node"

services:
- docker

# so the functional tests will work
addons:
apt:
packages:
- xvfb
install:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &

before_script:
- cd $TRAVIS_BUILD_DIR

script:
- ./runtests.sh
35 changes: 31 additions & 4 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

A new open source web interface for managing a SaltStack server. Built using vanilla ES6 and implemented as a wrapper around the rest_cherrypy server.


## Screenshots
![overview](/docs/overview.png)
![job](/docs/job.png)


## Features
- Login via PAM or any other supported authentication by Salt
- View minions and easily copy IPs
- Run state.highstate for a particular minion
- View the seven most recent jobs run on Salt
- Manually run any Salt function and see the output


## Quick start using PAM as authentication method
- Install `salt-api` - this is available in the Salt PPA package which should already been installed if you're using Salt
- Open the master config /etc/salt/master
Expand Down Expand Up @@ -59,8 +62,32 @@ docker-compose up
```
Then browse to [http://localhost:3333/](http://localhost:3333/), you can login with `salt:salt`.


## Testing
We provide some functional tests and unit tests. They use the docker setup to run the functional tests. You will also need [yarn](https://yarnpkg.com) and [node.js](https://nodejs.org/en/) to run them. When you have docker, yarn and node.js installed, you can run the tests from the root of the repository like this:
```
./runtests.sh
```

To show the browser window + a debugger while running the functional tests you can run:
```
NIGHTMARE_DEBUG=1 ./runtests.sh
```

We use the following testing libraries:
- [nightmare.js](https://github.com/segmentio/nightmare), for functional/browser tests
- [mocha](https://https://mochajs.org/), a well documented testing framework for javascript
- [chai](http://www.chaijs.com/), the preferred assertion library for testing

You'll need at least:
- `docker-compose` 1.12 or above
- `nodejs` 8.11 or above
- `yarn` 1.7 or above


## Contributing
- Just open a PR! Try to use no dependencies where possible, as vanilla JS is the aim. Any libraries will need to be heavily considered first.
Open a PR! Try to use no dependencies where possible, as vanilla JS is the aim. Any libraries will need to be heavily considered first. Please see the section above as PR's won't be reviewed if they don't pass the tests.


## Credits
This excellent frontend is originally written by [Oliver Dunk](https://github.com/oliverdunk).
Expand Down Expand Up @@ -89,8 +116,8 @@ This excellent frontend is originally written by [Oliver Dunk](https://github.co
## 1.0.1 (2018-05-16)
- Fixed position of popup when main window has scrolled (erwindon)
- Sort minions by hostname (erwindon)
- Fixed OS description in minion overview (No lsb_distrib_description) [#5](https://github.com/maerteijn/SaltGUI/issues/5) (erwindon)
- Now sort the jobs correctly on StartDate in the overview window [#6](https://github.com/maerteijn/SaltGUI/issues/6)
- Fixed OS description in minion overview (No lsb_distrib_description)(erwindon)
- Now sort the jobs correctly on ``StartDate`` in the overview window

## 1.0.0 (2018-03-07)
Original release with some styling fixes and with enabled the highstate functionality.
- Original release with some styling fixes and with enabled highstate functionality.
15 changes: 15 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Versions
--------
These docker images are build with Ubuntu 18.04 (bionic) and Debian 9 (stretch). They use the following repositories to install saltstack:
- https://repo.saltstack.com/apt/debian/9/amd64/latest
- http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest

Version of all salt packages installed: *2018.3.2+ds-1*

Docker images
-------------
Commands used to build these docker images::

docker build -f dockerfiles/dockerfile-saltmaster -t maerteijn/saltgui-saltmaster .
docker build -f dockerfiles/dockerfile-saltminion-debian -t maerteijn/saltgui-saltminion-debian .
docker build -f dockerfiles/dockerfile-saltminion-ubuntu -t maerteijn/saltgui-saltminion-ubuntu .
12 changes: 3 additions & 9 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
version: '3'
services:
saltmaster-local:
build:
context: .
dockerfile: ./dockerfiles/dockerfile-saltmaster
image: maerteijn/saltgui-saltmaster
ports:
- 4505:4505
- 4506:4506
Expand All @@ -14,18 +12,14 @@ services:
entrypoint: /usr/bin/supervisord

saltminion-ubuntu:
build:
context: .
dockerfile: ./dockerfiles/dockerfile-saltminion-ubuntu
image: maerteijn/saltgui-saltminion-ubuntu
depends_on:
- saltmaster-local
restart: on-failure
command: /usr/bin/salt-minion

saltminion-debian:
build:
context: .
dockerfile: ./dockerfiles/dockerfile-saltminion-debian
image: maerteijn/saltgui-saltminion-debian
depends_on:
- saltmaster-local
restart: on-failure
Expand Down
17 changes: 10 additions & 7 deletions docker/dockerfiles/dockerfile-saltmaster
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
FROM ubuntu
FROM ubuntu:18.04
MAINTAINER Martijn Jacobs <martijn@devopsconsulting.nl>

ENV REFRESHED_ON "7 Mar 2018"
ENV REFRESHED_ON "24 Jul 2018"
ENV DEBIAN_FRONTEND noninteractive

# add saltstack key and install gnupg2
RUN apt-get update && apt-get install curl --yes && apt-get install gnupg2 --yes
RUN curl --fail --silent --show-error --location https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
RUN echo 'deb http://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest xenial main' > /etc/apt/sources.list.d/saltstack.list
# add saltstack key and install dependencies
RUN apt-get update && apt-get install curl net-tools gnupg2 --yes
RUN curl --fail --silent --show-error --location https://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
RUN echo 'deb http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest bionic main' > /etc/apt/sources.list.d/saltstack.list

# install salt-master and salt-api, dependencies
RUN apt-get update && apt-get install salt-master --yes && apt-get install salt-api --yes
RUN apt-get update && apt-get install salt-master salt-api --yes

# add a user for the frontend salt:salt
RUN useradd -m -s/bin/bash -p $(openssl passwd -1 salt) salt
Expand All @@ -25,3 +25,6 @@ ADD ./conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# some volume configuration for the saltmaster
VOLUME ["/pki","/var/cache/salt","/var/log/salt"]
EXPOSE 3333 4505 4506

# show which versions are installed
RUN dpkg -l | grep salt\-
13 changes: 7 additions & 6 deletions docker/dockerfiles/dockerfile-saltminion-debian
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
FROM debian
FROM debian:9
MAINTAINER Martijn Jacobs <martijn@devopsconsulting.nl>

ENV REFRESHED_ON "7 Mar 2018"
ENV REFRESHED_ON "24 Jul 2018"
ENV DEBIAN_FRONTEND noninteractive

# some handy stuff to have
RUN apt-get update && apt-get install curl --yes && apt-get install gnupg --yes

# add saltstack key
# add saltstack key and install dependencies
RUN apt-get update && apt-get install curl gnupg net-tools --yes
RUN curl --fail --silent --show-error --location https://repo.saltstack.com/apt/debian/9/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
RUN echo 'deb http://repo.saltstack.com/apt/debian/9/amd64/latest stretch main' > /etc/apt/sources.list.d/saltstack.list

Expand All @@ -16,3 +14,6 @@ RUN apt-get update && apt-get install salt-minion --yes

# copy the minion configuration
ADD ./conf/minion /etc/salt/minion

# show which versions are installed
RUN dpkg -l | grep salt\-
17 changes: 9 additions & 8 deletions docker/dockerfiles/dockerfile-saltminion-ubuntu
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
FROM ubuntu
FROM ubuntu:18.04
MAINTAINER Martijn Jacobs <martijn@devopsconsulting.nl>

ENV REFRESHED_ON "7 Mar 2018"
ENV REFRESHED_ON "24 Jul 2018"
ENV DEBIAN_FRONTEND noninteractive

# some handy stuff to have and install gnupg2
RUN apt-get update && apt-get install curl --yes && apt-get install iproute2 --yes && apt-get install gnupg2 --yes

# add saltstack key
RUN curl --fail --silent --show-error --location https://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
RUN echo 'deb http://repo.saltstack.com/apt/ubuntu/16.04/amd64/latest xenial main' > /etc/apt/sources.list.d/saltstack.list
# add saltstack key and install dependencies
RUN apt-get update && apt-get install curl gnupg2 net-tools --yes
RUN curl --fail --silent --show-error --location https://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest/SALTSTACK-GPG-KEY.pub | apt-key add -
RUN echo 'deb http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest bionic main' > /etc/apt/sources.list.d/saltstack.list

# install salt-minion
RUN apt-get update && apt-get install salt-minion --yes

# copy the minion configuration
ADD ./conf/minion /etc/salt/minion

# show which versions are installed
RUN dpkg -l | grep salt\-
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
{
"name": "saltgui-linter",
"description": "Simple check for JSHint (Code Linting)",
"name": "saltgui-test",
"description": "Code linting and testing package for SaltGUI",
"author": "Martijn Jacobs",
"version": "0.0.1",
"license": "MIT",
"devDependencies": {
"jshint": "^2.9.5"
"chai": "^4.1.2",
"jshint": "^2.9.5",
"mocha": "^5.2.0",
"nightmare": "^3.0.1"
},
"jshintConfig": {
"esversion": 6
},
"scripts": {
"test": "jshint saltgui/"
"lint": "jshint saltgui/ tests/",
"wait-for-docker": "node tests/helpers/wait-for-docker.js",
"test": "mocha --trace-warnings --reporter spec tests/unit/ tests/functional/"
}
}
25 changes: 25 additions & 0 deletions runtests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# always cleanup the docker images when something goes wrong
function cleanupdocker {
docker-compose -f docker/docker-compose.yml rm -f -s
}
trap cleanupdocker EXIT

set -e
# add testing packages
yarn

# first see if we write es6 compatible js
yarn lint

# start a salt master, two salt minions and saltgui to run tests on
docker-compose -f docker/docker-compose.yml up -d

# wait until all are up
yarn wait-for-docker

# run the unittests/nightmare.js functional tests
yarn test

set +e
2 changes: 1 addition & 1 deletion saltgui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ <h1>SaltGUI</h1>
<!-- these can be added after testing to optgroup 'other' -->
<!-- add untested values to (new) optgroup 'experimental' on explicit user request -->
</select>
<input type='submit' value='Login'/>
<input type='submit' id='login-submit' value='Login'/>
<div class='attribution'>
<img src='static/images/github.png' />SaltGUI v1.2.0
</div>
Expand Down
12 changes: 5 additions & 7 deletions saltgui/static/scripts/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,11 @@ class API {
var params = {
};

return new Promise(function(resolve, reject) {
api._callMethod("POST", "/logout", params)
.then(function(data) {
window.sessionStorage.removeItem("token");
window.location.replace("/");
resolve();
}, reject);
return api._callMethod("POST", "/logout", params).then(response => {
window.sessionStorage.removeItem("token");
window.location.replace("/");
}).catch(error => {
console.error("_logout", error);
});
}

Expand Down
4 changes: 1 addition & 3 deletions saltgui/static/scripts/parsecmdline.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ window.parseCommandLine = function(toRun, args, params) {
endChar = ']';
objType = "array";
} else if(toRun[0] === '"') {
// note that json does not support single-quoted strings
endChar = '"';
objType = "double-quoted-string";
} else if(toRun[0] === '\'') {
endChar = '\'';
objType = "single-quoted-string";
}

var value;
Expand Down
6 changes: 3 additions & 3 deletions saltgui/static/scripts/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ class Router {
var router = this;
route.getPageElement().style.display = "";

document.querySelectorAll(".menu_item_active").forEach(
function (e){ e.classList.remove("menu_item_active"); }
);
Array.from(document.querySelectorAll(".menu_item_active")).forEach(
function (e){ e.classList.remove("menu_item_active"); }
);

var elem = route.getMenuItemElement();
if(elem) elem.classList.add("menu_item_active");
Expand Down
46 changes: 27 additions & 19 deletions saltgui/static/scripts/utils.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
window.elapsedToString = function(date) {
var secondsPassed = (new Date().getTime() / 1000) - (date.getTime() / 1000);
if(secondsPassed < 20) return "A few moments ago";
if(secondsPassed < 120) return "A few minutes ago";
try {
var secondsPassed = (new Date().getTime() / 1000) - (date.getTime() / 1000);

if(secondsPassed < 60 * 60) {
var minutes = Math.round(secondsPassed / 60);
return minutes + " minutes ago";
}
if(secondsPassed < 0) return "Magic happened in the future";
if(secondsPassed < 20) return "A few moments ago";
if(secondsPassed < 120) return "A few minutes ago";

if(secondsPassed < 60 * 60 * 24) {
var hours = Math.round(secondsPassed / 60 / 60);
return hours + " hours ago";
}
if(secondsPassed < 60 * 60) {
var minutes = Math.round(secondsPassed / 60);
return minutes + " minute(s) ago";
}

if(secondsPassed < 60 * 60 * 24 * 2) {
return "Yesterday";
}
if(secondsPassed < 60 * 60 * 24) {
var hours = Math.round(secondsPassed / 60 / 60);
return hours + " hour(s) ago";
}

if(secondsPassed < 60 * 60 * 24 * 30) {
var days = Math.round(secondsPassed / 60 / 60 / 24);
return days + " days ago";
}
if(secondsPassed < 60 * 60 * 24 * 2) {
return "Yesterday";
}

return "A long time ago, in a galaxy far, far away";
if(secondsPassed < 60 * 60 * 24 * 30) {
var days = Math.round(secondsPassed / 60 / 60 / 24);
return days + " days ago";
}

return "A long time ago, in a galaxy far, far away";
}
catch(err) {
console.error(err);
return "It did happen, when I don't know";
}
};

window.createElement = function(type, className, content) {
Expand Down
Loading

0 comments on commit f81c06f

Please sign in to comment.