Merge pull request #28 from moul/dev/moul/ci-integration

Run integration tests on CI
This commit is contained in:
Manfred Touron 2018-01-01 09:30:35 +01:00 committed by GitHub
commit d6ea80dab1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 196 additions and 134 deletions

View file

@ -1,11 +1,12 @@
defaults: &defaults
working_directory: /go/src/github.com/moul/sshportal
docker:
- image: circleci/golang:1.8
version: 2
jobs:
build:
docker:
- image: circleci/golang:1.8
# - image: circleci/mysql:9.4
working_directory: /go/src/github.com/moul/sshportal
go.build:
<<: *defaults
steps:
- checkout
- run: make install
@ -14,4 +15,26 @@ jobs:
# - run: make integration
- run: go get -u github.com/alecthomas/gometalinter
- run: gometalinter --install
- run: make lint
- run: make lint
docker.integration:
<<: *defaults
steps:
- checkout
- run:
name: Install Docker Compose
command: |
umask 022
curl -L https://github.com/docker/compose/releases/download/1.11.2/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
- setup_remote_docker:
docker_layer_caching: true
- run: docker build -t moul/sshportal .
- run: make integration
workflows:
version: 2
build_and_integration:
jobs:
- go.build
- docker.integration
# requires: docker.build?

View file

@ -2,8 +2,13 @@
## master (unreleased)
Breaking changes:
* Use `sshportal server` instead of `sshportal` to start a new server (nothing to change if using the docker image)
Changes:
* Fix connection failure when sending too many environment variables (fix [#22](https://github.com/moul/sshportal/issues/22))
* Fix panic when entering empty command (fix [#13](https://github.com/moul/sshportal/issues/13))
* Add `config backup --ignore-events` option
## v1.6.0 (2017-12-12)

View file

@ -8,3 +8,5 @@ RUN make _docker_install
FROM scratch
COPY --from=builder /go/bin/sshportal /bin/sshportal
ENTRYPOINT ["/bin/sshportal"]
CMD ["server"]
EXPOSE 2222

View file

@ -3,7 +3,6 @@ GIT_TAG ?= $(shell git describe --tags --always)
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
LDFLAGS ?= -X main.GitSha=$(GIT_SHA) -X main.GitTag=$(GIT_TAG) -X main.GitBranch=$(GIT_BRANCH)
VERSION ?= $(shell grep 'VERSION =' main.go | cut -d'"' -f2)
PORT ?= 2222
AES_KEY ?= my-dummy-aes-key
.PHONY: install
@ -16,7 +15,7 @@ docker.build:
.PHONY: integration
integration:
PORT="$(PORT)" bash ./examples/integration/test.sh
cd ./examples/integration && make
.PHONY: _docker_install
_docker_install:

View file

@ -0,0 +1,4 @@
FROM occitech/ssh-client
COPY . /integration
ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/integration/_client.sh"]

View file

@ -0,0 +1,6 @@
run:
docker-compose down
docker-compose up -d sshportal
docker-compose build client
docker-compose run client /integration/_client.sh
docker-compose down

56
examples/integration/_client.sh Executable file
View file

@ -0,0 +1,56 @@
#!/bin/sh -e
mkdir -p ~/.ssh
cp /integration/client_test_rsa ~/.ssh/id_rsa
chmod -R 700 ~/.ssh
cat >~/.ssh/config <<EOF
Host sshportal
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
Port 2222
HostName sshportal
EOF
#ping -c 1 sshportal
sleep 3
set -x
# login
ssh sshportal -l invite:integration
# hostgroup/usergroup/acl
ssh sshportal -l admin hostgroup create
ssh sshportal -l admin hostgroup create --name=hg1
ssh sshportal -l admin hostgroup create --name=hg2 --comment=test
ssh sshportal -l admin usergroup inspect hg1 hg2
ssh sshportal -l admin hostgroup ls
ssh sshportal -l admin usergroup create
ssh sshportal -l admin usergroup create --name=ug1
ssh sshportal -l admin usergroup create --name=ug2 --comment=test
ssh sshportal -l admin usergroup inspect ug1 ug2
ssh sshportal -l admin usergroup ls
ssh sshportal -l admin acl create --ug=ug1 --ug=ug2 --hg=hg1 --hg=hg2 --comment=test --action=allow --weight=42
ssh sshportal -l admin acl inspect 2
ssh sshportal -l admin acl ls
# basic host create
ssh sshportal -l admin host create bob@example.org:1234
ssh sshportal -l admin host create test42
ssh sshportal -l admin host create --name=testtest --comment=test --password=test test@test.test
ssh sshportal -l admin host create --group=hg1 --group=hg2 hostwithgroups.org
ssh sshportal -l admin host inspect example test42 testtest hostwithgroups
ssh sshportal -l admin host ls
# backup/restore
ssh sshportal -l admin config backup --indent --ignore-events > backup-1
ssh sshportal -l admin config restore --confirm < backup-1
ssh sshportal -l admin config backup --indent --ignore-events > backup-2
(
cat backup-1 | grep -v '"date":' | grep -v 'tedAt":' > backup-1.clean
cat backup-2 | grep -v '"date":' | grep -v 'tedAt":' > backup-2.clean
set -xe
diff backup-1.clean backup-2.clean
)

View file

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxV0ds/oMuOw9QVLFgxaM0Js2IdJKiYLnmKq96IuZ/wMqMea3
qi1UfNBPUQ2CojwbJGTea8cA9J1Et+a6v1mL66YG8zyxmhdlKHm2KOMnUXSfWPNg
ZArXH7Uj4Nx1k/O1ujfQFAsYTx63kMqwq1lM9JrExLSdp/8D/zQAyF68c82w8UZH
aIpLZJkM/fgh0VJWiw65NYAzuIkJNBgZR8rEBQU7V3lCqFGcSJ88MoqIdVGy0I4b
GGpO9VppDTf+uYGYDthhXlV0nHM45neWL5hzFK6oqbLFLpsaUOY7C3kKv+8+B3lX
p3OfGVoFy7u3evro+yRQEMQ+myS5UBIHaI3qOwIDAQABAoIBABM7/vASV3kSNOoP
2gXrha+y4LStHOyH4HBFe5qVOF3c/hi85ntkTY6YcpJwoaGUAAUs+2w/ib1NMmxF
xT9ux68gkB7WdGyTCR3HttQHR0at+fWeSm+Vit+hNKzub1sK7lQGqnW5mxXi5Xrr
9gnM+y3/g1u0SoUb2lTdyZG9gdo7LnLElzRinraEqTJUowXkqzAhGf1A+Kgp2fkb
/+QP1oiK8QeOFOsITD2UwIVCBRwRl5TjjwfLQ4El6oAWNjcL1ZfSmQLiXZ7U8Smk
Cd+BI+6ZDLA43fBUGDjbg4+2dt2JoKNkS0FfqhCW+Z2A0+ClJ8pwuMqRz8XXaOYr
ONCqOPECgYEA/qyWxSUjEWMvN3tC/mZPEbwHP3m7mbR1KGwhZylWVCmEF7kVC6il
/ICQZUI9ekyGJZ/SKZKwxDe7oeV+vFsus/9FWC5wrp45Xm4kEUwsBr4bWvuNpVOq
jrKecY8NgPZS1X6Uc5BbpiE9/VF2gCdYVVCDXP1NfO2MDhkniXJQUEMCgYEAxmQl
3s/vih9rXllPZcWHafjnFcGU1AIiJD1c+8lAqwCZzm0Bt0Ex4s1t3lp0ew6YBVXN
yGy+BORxOC9FQGTlKZNk/S705+8iAVNc9Sy7XbgN3GY3eat7XYbNpGbQrjiyZ+7I
pdEnoHWQD4NFXHaVsXaVHcBFUovXKoes2PODeqkCgYEAoN/3Ucv2zgoAjqSfmkKY
mhRT48YLOroi9AjyRM95CCs9lRrGb5n2WH4COOTSHwpuByBhSv+uCBVIwqlNGMDk
zLFpZZ3YcoXiqYMb541dlljKwPt8673hVMkCi6uZFSkFBHY0YpgDPPtsxDOMjsHL
7ACzKq+cHlmUimdbcViz4S8CgYEAr2+sVYaHixsRtVNA9PxiLQIgR4rx8zEXw/hH
m5hyiUV0vaiDlewfEzMab0CKNK/JGx6vZQdUWbsxq7+Re8o9JDDlY0b854T+CzIO
x/iQj+XMzBPQBtXvt9sXSsRo0Uft7B6qbIeyhSCxDibFVWjAIzh70N1P8BkdYsyr
uwZMRFECgYEA5QuutlFLI7hMPdBQvsEhjdVwKAj7LvpNemgxDpEoMiQWWm51XzcP
IZjlCwl1UvIE0MxowtvNr5lQuGRN8/88Dajpq+W6eeTSCKi67nn0VZh13cQLKvoX
DRZ6nfC3iLnEYKK+KN/I3NY7JcSjHmW6V8WtrCYAi2D5Ns05XJAG6t8=
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,18 @@
version: '3.0'
services:
sshportal:
image: moul/sshportal
environment:
- SSHPORTAL_DEFAULT_ADMIN_INVITE_TOKEN=integration
command: server --debug
ports:
- 2222
client:
build: .
depends_on:
- sshportal
#volumes:
# - .:/integration
tty: true

View file

@ -1,87 +0,0 @@
#!/bin/sh -e
# Setup a new sshportal and performs some checks
PORT=${PORT:-2222}
SSHPORTAL_DEFAULT_ADMIN_INVITE_TOKEN=integration
# tempdir
WORK_DIR=`mktemp -d`
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
echo "Could not create temp dir"
exit 1
fi
cd "${WORK_DIR}"
# pre cleanup
docker_cleanup() {
( set -x
docker rm -f -v sshportal-integration 2>/dev/null >/dev/null || true
)
}
tempdir_cleanup() {
rm -rf "${WORK_DIR}"
}
docker_cleanup
trap tempdir_cleanup EXIT
# start server
( set -xe;
docker run \
-d \
-e SSHPORTAL_DEFAULT_ADMIN_INVITE_TOKEN=${SSHPORTAL_DEFAULT_ADMIN_INVITE_TOKEN} \
--name=sshportal-integration \
-p${PORT}:2222 \
moul/sshportal --debug
)
while ! nc -z localhost ${PORT}; do
sleep 1
done
sleep 3
# integration suite
xssh() {
set -e
echo "+ ssh {sshportal} $@" >&2
ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost -p ${PORT} $@
}
# login
xssh -l invite:integration
# hostgroup/usergroup/acl
xssh -l admin hostgroup create
xssh -l admin hostgroup create --name=hg1
xssh -l admin hostgroup create --name=hg2 --comment=test
xssh -l admin usergroup inspect hg1 hg2
xssh -l admin hostgroup ls
xssh -l admin usergroup create
xssh -l admin usergroup create --name=ug1
xssh -l admin usergroup create --name=ug2 --comment=test
xssh -l admin usergroup inspect ug1 ug2
xssh -l admin usergroup ls
xssh -l admin acl create --ug=ug1 --ug=ug2 --hg=hg1 --hg=hg2 --comment=test --action=allow --weight=42
xssh -l admin acl inspect 2
xssh -l admin acl ls
# basic host create
xssh -l admin host create bob@example.org:1234
xssh -l admin host create test42
xssh -l admin host create --name=testtest --comment=test --password=test test@test.test
xssh -l admin host create --group=hg1 --group=hg2 hostwithgroups.org
xssh -l admin host inspect example test42 testtest hostwithgroups
xssh -l admin host ls
# backup/restore
xssh -l admin config backup --indent > backup-1
xssh -l admin config restore --confirm < backup-1
xssh -l admin config backup --indent > backup-2
(
cat backup-1 | grep -v '"date":' > backup-1.clean
cat backup-2 | grep -v '"date":' > backup-2.clean
set -xe
diff backup-1.clean backup-2.clean
)
# post cleanup
#cleanup

View file

@ -9,7 +9,7 @@ services:
condition: service_healthy
links:
- mysql
command: --db-driver=mysql --debug --db-conn="root:root@tcp(mysql:3306)/db?charset=utf8&parseTime=true&loc=Local"
command: server --db-driver=mysql --debug --db-conn="root:root@tcp(mysql:3306)/db?charset=utf8&parseTime=true&loc=Local"
ports:
- 2222:2222

76
main.go
View file

@ -45,43 +45,49 @@ func main() {
app.Author = "Manfred Touron"
app.Version = Version + " (" + GitSha + ")"
app.Email = "https://github.com/moul/sshportal"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "bind-address, b",
EnvVar: "SSHPORTAL_BIND",
Value: ":2222",
Usage: "SSH server bind address",
},
cli.StringFlag{
Name: "db-driver",
Value: "sqlite3",
Usage: "GORM driver (sqlite3)",
},
cli.StringFlag{
Name: "db-conn",
Value: "./sshportal.db",
Usage: "GORM connection string",
},
cli.BoolFlag{
Name: "debug, D",
Usage: "Display debug information",
},
cli.StringFlag{
Name: "config-user",
Usage: "SSH user that spawns a configuration shell",
Value: "admin",
},
cli.StringFlag{
Name: "healthcheck-user",
Usage: "SSH user that returns healthcheck status without checking the SSH key",
Value: "healthcheck",
},
cli.StringFlag{
Name: "aes-key",
Usage: "Encrypt sensitive data in database (length: 16, 24 or 32)",
app.Commands = []cli.Command{
{
Name: "server",
Usage: "Start sshportal server",
Action: server,
Flags: []cli.Flag{
cli.StringFlag{
Name: "bind-address, b",
EnvVar: "SSHPORTAL_BIND",
Value: ":2222",
Usage: "SSH server bind address",
},
cli.StringFlag{
Name: "db-driver",
Value: "sqlite3",
Usage: "GORM driver (sqlite3)",
},
cli.StringFlag{
Name: "db-conn",
Value: "./sshportal.db",
Usage: "GORM connection string",
},
cli.BoolFlag{
Name: "debug, D",
Usage: "Display debug information",
},
cli.StringFlag{
Name: "config-user",
Usage: "SSH user that spawns a configuration shell",
Value: "admin",
},
cli.StringFlag{
Name: "healthcheck-user",
Usage: "SSH user that returns healthcheck status without checking the SSH key",
Value: "healthcheck",
},
cli.StringFlag{
Name: "aes-key",
Usage: "Encrypt sensitive data in database (length: 16, 24 or 32)",
},
},
},
}
app.Action = server
if err := app.Run(os.Args); err != nil {
log.Fatalf("error: %v", err)
}

View file

@ -299,6 +299,7 @@ GLOBAL OPTIONS:
Flags: []cli.Flag{
cli.BoolFlag{Name: "indent", Usage: "uses indented JSON"},
cli.BoolFlag{Name: "decrypt", Usage: "decrypt sensitive data"},
cli.BoolFlag{Name: "ignore-events", Usage: "do not backup events data"},
},
Description: "ssh admin@portal config backup > sshportal.bkp",
Action: func(c *cli.Context) error {
@ -360,8 +361,10 @@ GLOBAL OPTIONS:
if err := SessionsPreload(db).Find(&config.Sessions).Error; err != nil {
return err
}
if err := EventsPreload(db).Find(&config.Events).Error; err != nil {
return err
if !c.Bool("ignore-events") {
if err := EventsPreload(db).Find(&config.Events).Error; err != nil {
return err
}
}
config.Date = time.Now()
enc := json.NewEncoder(s)