Merge branch 'develop' into gometalinter

This commit is contained in:
Tom Whiston 2018-04-06 12:27:53 +02:00 committed by GitHub
commit 9931f15cd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 496 additions and 236 deletions

View File

@ -1,94 +1,253 @@
# This configuration was automatically generated from a CircleCI 1.0 config.
# Workflow based configuration
version: 2
aliases:
- &golang-image
image: circleci/golang:1.10
- &working-dir
/go/src/github.com/ansible-semaphore/semaphore
- &store-bin-artifacts
store_artifacts:
path: /go/src/github.com/ansible-semaphore/semaphore/bin
- &install-task-binary
run:
name: install task binary
command: |
cd /go/bin
curl -L https://github.com/go-task/task/releases/download/v2.0.1/task_linux_amd64.tar.gz | tar xvz
cd -
- &persist-bin
persist_to_workspace:
root: .
paths:
- bin/*
- &install-node
run:
name: Install node
command: |
set +e
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 8.2.0 && nvm alias default 8.2.0
# Each step uses the same `$BASH_ENV`, so need to modify it
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
- &test-compile-changes
run:
name: test that compile did not create/modify untracked files
command: git diff --exit-code --stat -- . ':(exclude)web/package-lock.json'
- &save-npm-cache
save_cache:
key: v1-npm-deps-{{ checksum "web/package.json" }}
paths:
- web/node_modules
- &save-go-cache
save_cache:
key: v1-go-deps-{{ checksum "Gopkg.lock" }}-{{ checksum "Gopkg.toml" }}
paths:
- vendor
- &load-npm-cache
restore_cache:
keys:
- v1-npm-deps-{{ checksum "web/package.json" }}
- v1-npm-deps-
- &load-go-cache
restore_cache:
keys:
- v1-go-deps-{{ checksum "Gopkg.lock" }}-{{ checksum "Gopkg.toml" }}
- v1-go-deps-{{ checksum "Gopkg.lock" }}
- v1-go-deps-
jobs:
build:
machine: true
# we hard code this because even in a fork our code references the canonical import urls
working_directory: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore
build:local:
docker:
- *golang-image
working_directory: *working-dir
steps:
# Remove go and restore the dependency cache
- run: sudo rm -rf /usr/local/go
- run: mkdir -p ${GOPATH}/bin
- restore_cache:
keys:
# This branch if available
- v4-dep-{{ .Branch }}-
# Default branch if not
- v4-dep-develop-
# Any branch if there are none on the default branch - this should be unnecessary if you have your default branch configured correctly
- v4-dep-
- run: sudo apt-get update
- run: sudo apt-get install rpm
# Install node and go
- run:
name: Install node
command: |
set +e
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 8.2.0 && nvm alias default 8.2.0
# Each step uses the same `$BASH_ENV`, so need to modify it
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
- run: sudo curl -L https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz > /tmp/go.tar.gz
- run: sudo tar -C /usr/local -xzf /tmp/go.tar.gz
# Needed for task orchestration
- run: go get -u -v github.com/go-task/task/cmd/task
# Needed only in ci to post coverage reports
- run: go get github.com/schrej/godacov
# Get app and install all its deps
- checkout
# Circle can provide a concatenated gopath and the second item is not actually in the path
# which will cause builds to fail if deps are placed there
- run: GOPATH=/home/circleci/.go_workspace task deps
- run: task deps:docker
# Save dependency cache
- save_cache:
key: v4-dep-{{ .Branch }}-{{ epoch }}
paths:
- ~/.go_workspace/src/github.com/ansible-semaphore/semaphore
- ~/.go_workspace/bin
- /opt/circleci/.nvm
# Post cache compile
- run: task compile
- run: task lint:be
# Test
# This looks like utter filth in circleci v2 but we have no choice apart from this escaping madness
- run: "cat > config.json <<EOF\n{\n\t\"mysql\": {\n\t\t\"host\": \"0.0.0.0:3306\"\
,\n\t\t\"user\": \"root\",\n\t\t\"pass\": \"\",\n\t\t\"name\": \"circle_test\"\
\n\t},\n\t\"email_alert\": false\n}\nEOF\n"
- run: |
docker run -d -p "3306:3306" --health-cmd='mysqladmin ping --silent' -e MYSQL_ALLOW_EMPTY_PASSWORD=true -e MYSQL_DATABASE=circle_test --name=mysql mysql:5.6
function getContainerHealth {
docker inspect --format "{{json .State.Health.Status }}" $1
}
- run: export
- *install-node
- *install-task-binary
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- *save-go-cache
- *save-npm-cache
- run: task compile
- *test-compile-changes
- run: task build:local
- *store-bin-artifacts
- *persist-bin
function waitContainer {
while STATUS=$(getContainerHealth $1); [ $STATUS != "\"healthy\"" ]; do
if [ $STATUS == "\"unhealthy\"" ]; then
exit -1
fi
printf .
sleep 1
done
}
build:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-node
- *install-task-binary
- run: sudo apt-get install rpm
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- run: task compile
- *test-compile-changes
- run: task build
- *store-bin-artifacts
waitContainer mysql
- run: go run cli/main.go --migrate -config config.json
- run: docker stop mysql && docker rm mysql
- run: task test
- run: context=prod task docker:test
# Build artifacts for all architectures
- run: task build
# Post coverage
- run: godacov -t "${CODACY_TOKEN}" -r ./coverage.out -c "${CIRCLE_SHA1}" || true
# Teardown
# Save test results
- store_test_results:
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/coverage.out
# Save artifacts
- store_artifacts:
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/bin
- store_artifacts:
path: ~/.go_workspace/src/github.com/ansible-semaphore/semaphore/coverage.out
# Run goverage and post results
test:golang:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-task-binary
# Needed only in ci to post coverage reports
- run: go get github.com/schrej/godacov
- checkout
- *load-go-cache
- run: task deps:tools
- run: task deps:be
- run: task compile:be
- run: task lint:be
- run: task test
- run: godacov -t "${CODACY_TOKEN}" -r ./coverage.out -c "${CIRCLE_SHA1}" || true
- store_test_results:
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
- store_artifacts:
path: /go/src/github.com/ansible-semaphore/semaphore/coverage.out
test:integration:
docker:
- *golang-image
- image: circleci/mysql
working_directory: *working-dir
steps:
- attach_workspace:
at: *working-dir
# This looks like utter filth in circleci v2 but we have no choice apart from this escaping madness
- run: "cat > config.json <<EOF\n{\n\t\"mysql\": {\n\t\t\"host\": \"127.0.0.1:3306\"\
,\n\t\t\"user\": \"root\",\n\t\t\"pass\": \"\",\n\t\t\"name\": \"circle_test\"\
\n\t},\n\t\"email_alert\": false\n}\nEOF\n"
- run:
name: Wait for db
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
- run: bin/semaphore --migrate -config config.json
# TODO - Here we could do some api/functional testing
test:docker:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: context=prod task docker:test
deploy:dev:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
- run: context=prod tag=develop task docker:build
- run: tag=develop task docker:push
deploy:prod:
docker:
- *golang-image
steps:
- *install-task-binary
- checkout
- setup_remote_docker
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
- run: context=prod tag=latest task docker:build
- run: tag=latest task docker:push
- docker tag ansiblesemaphore/semaphore:latest ansiblesemaphore/semaphore:$CIRCLE_TAG
- run: tag=$CIRCLE_TAG task docker:push
release:
docker:
- *golang-image
working_directory: *working-dir
steps:
- *install-node
- *install-task-binary
- run: sudo apt-get install rpm
- checkout
- *load-go-cache
- *load-npm-cache
- run: task deps
- run: task compile
- *test-compile-changes
- run: task release
- *store-bin-artifacts
workflows:
version: 2
build-deploy:
jobs:
- test:docker
- test:golang
- build:local
- test:integration:
requires:
- build:local
# Don't build on master because build is just a gorelease without the release
- build:
requires:
- test:golang
- test:integration
filters:
branches:
ignore: master
# Dev deploys require all tests to pass and app builds
- deploy:dev:
requires:
- build
- test:docker
filters:
branches:
only: develop
# Production deploys only happen if everything passes
# and we have a tag starting with v
- release:
requires:
- test:golang
- test:integration
filters:
branches:
only: master
tags:
only: /^v.*/
# This deploy also happens on develop so we can publish beta/rc images
- deploy:prod:
requires:
- test:docker
- release
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/

3
.gitignore vendored
View File

@ -9,7 +9,8 @@ config.json
node_modules/
.idea/
bin/
/bin/
*-packr.go
util/version.go
/vendor/

View File

@ -34,7 +34,6 @@ git clone --recursive git@github.com:ansible-semaphore/semaphore.git && cd semap
3) Install dev dependencies
```
go get ./...
go get -u github.com/go-task/task/cmd/task
task deps
```

View File

@ -6,6 +6,7 @@
[![semaphore on discord](https://img.shields.io/badge/discord-semaphore%20community-738bd7.svg)](https://discord.gg/ZW7Qu6a)
- [Releases](https://github.com/ansible-semaphore/semaphore/releases)
- [Docker Hub](https://hub.docker.com/r/ansiblesemaphore/semaphore/)
- [Install Instructions](https://github.com/ansible-semaphore/semaphore/wiki/Installation)
- [Troubleshooting](https://github.com/ansible-semaphore/semaphore/wiki/Troubleshooting)
- [Contribution Guide](https://github.com/ansible-semaphore/semaphore/blob/develop/CONTRIBUTING.md)

View File

@ -5,6 +5,10 @@
# internally by other tasks and therefore are not listed when running `task` or `task -l`
version: '2'
vars:
docker_namespace: ansiblesemaphore
docker_image: semaphore
tasks:
all:
desc: Install, Compile, Test and Build Semaphore for local architecture
@ -30,7 +34,6 @@ tasks:
desc: Installs npm requirements for front end from package.json
dir: web
cmds:
- npm i -g less pug-cli
- npm install
deps:tools:
@ -39,13 +42,12 @@ tasks:
vars:
GORELEASER_VERSION: "0.62.5"
cmds:
- npm install -g nodemon
- go get -u github.com/golang/dep/cmd/dep
- go get github.com/cespare/reflex || true
- go get -u github.com/gobuffalo/packr/...
- go get -u github.com/haya14busa/goverage
- '{{ if ne OS "windows" }} curl -L https://github.com/goreleaser/goreleaser/releases/download/v{{ .GORELEASER_VERSION }}/goreleaser_$(uname -s)_$(uname -m).tar.gz | tar -xz -C ${GOPATH}/bin{{ else }}ver>nul{{ end }}'
- '{{ if ne OS "windows" }} chmod +x ${GOPATH}/bin/goreleaser{{ else }}ver>nul{{ end }}'
- '{{ if ne OS "windows" }} curl -L https://github.com/goreleaser/goreleaser/releases/download/v{{ .GORELEASER_VERSION }}/goreleaser_$(uname -s)_$(uname -m).tar.gz | tar -xz -C ${GOPATH}/bin{{ else }} {{ end }}'
- '{{ if ne OS "windows" }} chmod +x ${GOPATH}/bin/goreleaser{{ else }} {{ end }}'
- '{{ if eq OS "windows" }} echo "NOTICE: You must download goreleaser manually to build this application https://github.com/goreleaser/goreleaser/releases "{{ else }}:{{ end }}'
- go get -u github.com/alecthomas/gometalinter
- gometalinter --install
@ -69,8 +71,8 @@ tasks:
- public/html/**/*.html
- bundle.json
cmds:
- lessc resources/less/semaphore.less > public/css/semaphore.css
- pug resources/pug --out public/html
- ./node_modules/.bin/lessc resources/less/semaphore.less > public/css/semaphore.css
- ./node_modules/.bin/pug resources/pug --out public/html
- cp node_modules/font-awesome/fonts/* public/fonts
- node bundler.js
@ -91,7 +93,8 @@ tasks:
BRANCH:
sh: git rev-parse --abbrev-ref HEAD
DIRTY:
sh: git status --porcelain
# We must exclude the package-lock file as npm install can change it!
sh: git diff --exit-code --stat -- . ':(exclude)web/package-lock.json'
SHA:
sh: git log --pretty=format:'%h' -n 1
TIMESTAMP:
@ -111,9 +114,9 @@ tasks:
watch:fe:
dir: web
cmds:
- nodemon -w js -i bundle.js -e js bundler.js &
- nodemon -w css -e less --exec "lessc resources/less/semaphore.less > public/css/semaphore.css" &
- pug -w -P --doctype html resources/pug --out public/html &
- ./node_modules/.bin/nodemon -w js -i bundle.js -e js bundler.js &
- ./node_modules/.bin/nodemon -w css -e less --exec "lessc resources/less/semaphore.less > public/css/semaphore.css" &
- ./node_modules/.bin/pug -w -P --doctype html resources/pug --out public/html &
build:
desc: Build a full set of release binaries and packages
@ -228,7 +231,7 @@ tasks:
context: "{{ .context }}"
action: build
tag: "{{ .tag }}"
args: -t castawaylabs/semaphore:{{ .tag }} .
args: -t "{{ .docker_namespace }}/{{ .docker_image }}:{{ .tag }}" .
deps:docker:
desc: Install docker testing dependencies. These must be installed explicitly and are not included in the general deps task.
@ -255,13 +258,13 @@ tasks:
vars:
tag: "{{ .context }}-test"
- task: docker:goss
- docker rmi "castawaylabs/semaphore:{{ .context }}-test"
- docker rmi "{{ .docker_namespace }}/{{ .docker_image }}:{{ .context }}-test"
docker:goss:
dir: "deployment/docker/{{ .context}}"
deps: ['deps:docker']
cmds:
- GOSS_FILES_STRATEGY='cp' dgoss run -it "castawaylabs/semaphore:{{ .context }}-test"
- GOSS_FILES_STRATEGY='cp' dgoss run -it "{{ .docker_namespace }}/{{ .docker_image }}:{{ .context }}-test"
docker:lint:
desc: hadolint a dockerfile. Ignores version pinning warning
@ -269,6 +272,11 @@ tasks:
cmds:
- hadolint Dockerfile --ignore DL3018
docker:push:
desc: push a docker image to a repo. Defaults to the official docker hub
cmds:
- docker push {{ .docker_namespace }}/{{ .docker_image }}:{{ .tag }}
# templated command to reduce code duplication
docker:
vars:

View File

@ -1,6 +1,6 @@
# Docker Deployments
Production images for each tag, latest and the development branch will be pushed to [docker hub](https://hub.docker.com/r/castawaylabs/semaphore).
Production images for each tag, latest and the development branch will be pushed to [docker hub](https://hub.docker.com/r/ansiblesemaphore/semaphore).
To build images locally see the contexts included here and use the `d` and `dc` tasks in the root Taskfile.yml to help with building and running.
## Contexts
@ -11,7 +11,7 @@ To build a production image you should run
context=prod task docker:build
this will create an image called `castawaylabs/semaphore:latest` which will be compiled from the currently checked out code
this will create an image called `ansiblesemaphore/semaphore:latest` which will be compiled from the currently checked out code
This image is run as non root user 1001 (for PaaS systems such as openshift) and is build on alpine with added glibc.
With ansible etc... installed in the container it is ~283MiB in size.

View File

@ -10,7 +10,7 @@ services:
MYSQL_PASSWORD: semaphore
semaphore_dev:
image: castawaylabs/semaphore-dev:latest
image: ansiblesemaphore/semaphore:dev-compose
build:
context: ./../../../
dockerfile: ./deployment/docker/dev/Dockerfile

View File

@ -8,7 +8,6 @@ export PATH="${PATH}:${GOBIN}"
# Get prerequisites for building the app
go get -u -v github.com/go-task/task/cmd/task
go get ./...
# Compile and build
task deps

View File

@ -13,7 +13,7 @@ services:
MYSQL_PASSWORD: hx4hjxqthfwbfsy5535u4agfdscm
semaphore:
image: castawaylabs/semaphore:prod
image: ansiblesemaphore/semaphore:prod-compose
build:
context: ./../../../
dockerfile: ./deployment/docker/prod/Dockerfile
@ -31,7 +31,7 @@ services:
depends_on:
- mysql
semaphore_proxy:
image: castawaylabs/semaphore:proxy
image: ansiblesemaphore/proxy:latest
build:
context: ./proxy
ports:

View File

@ -19,7 +19,11 @@
"requirejs": "^2.3.5",
"sweetalert": "^2.1.0"
},
"devDependencies": {},
"devDependencies": {
"less": "^3.0.1",
"pug-cli": "^1.0.0-alpha6",
"nodemon": "^1.17.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},

View File

@ -5,7 +5,7 @@ define(function () {
$scope.alert_chat = Project.alert_chat;
$scope.save = function (name, alert, alert_chat) {
$http.put(Project.getURL(), { name: name, alert: alert, alert_chat: alert_chat}).then(function () {
$http.put(Project.getURL(), {name: name, alert: alert, alert_chat: alert_chat}).then(function () {
swal('Saved', 'Project settings saved.', 'success');
}).catch(function () {
swal('Error', 'Project settings were not saved', 'error');
@ -16,15 +16,28 @@ define(function () {
swal({
title: 'Delete Project?',
text: 'All data related to this project will be deleted.',
type: 'warning',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Yes, DELETE'
}, function () {
$http.delete(Project.getURL()).then(function () {
$state.go('dashboard');
}).catch(function () {
swal('error', 'could not delete project!', 'error');
icon: 'warning',
buttons: {
cancel: true,
confirm: {
text: 'Yes, DELETE',
closeModal: false,
className: 'bg-danger',
},
},
}).then(function (value) {
if (!value) {
return;
}
$http.delete(Project.getURL())
.then(function () {
swal.stopLoading();
swal.close();
$state.go('dashboard');
}).catch(function () {
swal('Error', 'Could not delete project!', 'error');
});
});
}

View File

@ -7,30 +7,46 @@ define(function () {
}
$scope.remove = function (environment) {
$http.delete(Project.getURL() + '/environment/' + environment.id).then(function () {
$scope.reload();
}).catch(function (response) {
var d = response.data;
if (!(d && d.inUse)) {
swal('error', 'could not delete environment..', 'error');
return;
}
swal({
title: 'Environment in use',
text: d.error,
type: 'error',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Mark as removed'
}, function () {
$http.delete(Project.getURL() + '/environment/' + environment.id + '?setRemoved=1').then(function () {
$scope.reload();
}).catch(function () {
$http.delete(Project.getURL() + '/environment/' + environment.id)
.then(function () {
$scope.reload();
})
.catch(function (response) {
var d = response.data;
if (!(d && d.inUse)) {
swal('error', 'could not delete environment..', 'error');
return;
}
swal({
title: 'Environment in use',
text: d.error,
icon: 'error',
buttons: {
cancel: true,
confirm: {
text: 'Mark as removed',
closeModel: false,
className: 'bg-danger',
}
}
}).then(function (value) {
if (!value) {
return;
}
$http.delete(Project.getURL() + '/environment/' + environment.id + '?setRemoved=1')
.then(function () {
swal.stopLoading();
swal.close();
$scope.reload();
})
.catch(function () {
swal('Error', 'Could not delete environment..', 'error');
});
});
});
});
}
$scope.add = function () {
@ -44,12 +60,13 @@ define(function () {
scope: scope
}).result.then(function (env) {
$http.post(Project.getURL() + '/environment', env.environment)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Environment not added: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.editEnvironment = function (env) {
@ -65,12 +82,13 @@ define(function () {
}
$http.put(Project.getURL() + '/environment/' + env.id, opts.environment)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Environment not updated: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.reload();

View File

@ -7,30 +7,47 @@ define(function () {
}
$scope.remove = function (inventory) {
$http.delete(Project.getURL() + '/inventory/' + inventory.id).then(function () {
$scope.reload();
}).catch(function (response) {
var d = response.data;
if (!(d && d.inUse)) {
swal('error', 'could not delete inventory..', 'error');
return;
}
swal({
title: 'Inventory in use',
text: d.error,
type: 'error',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Mark as removed'
}, function () {
$http.delete(Project.getURL() + '/inventory/' + inventory.id + '?setRemoved=1').then(function () {
$scope.reload();
}).catch(function () {
$http.delete(Project.getURL() + '/inventory/' + inventory.id)
.then(function () {
$scope.reload();
})
.catch(function (response) {
var d = response.data;
if (!(d && d.inUse)) {
swal('error', 'could not delete inventory..', 'error');
return;
}
swal({
title: 'Inventory in use',
text: d.error,
icon: 'error',
buttons: {
cancel: true,
confirm: {
text: 'Mark as removed',
closeModel: false,
className: 'bg-danger',
}
}
}).then(function (value) {
if (!value) {
return;
}
$http
.delete(Project.getURL() + '/inventory/' + inventory.id + '?setRemoved=1')
.then(function () {
swal.stopLoading();
swal.close();
$scope.reload();
})
.catch(function () {
swal('Error', 'Could not delete inventory..', 'error');
});
});
});
});
}
$scope.add = function () {
@ -43,12 +60,13 @@ define(function () {
scope: scope
}).result.then(function (inventory) {
$http.post(Project.getURL() + '/inventory', inventory.inventory)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Inventory not added: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
});
}
@ -68,12 +86,13 @@ define(function () {
}
$http.put(Project.getURL() + '/inventory/' + inventory.id, opts.inventory)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Inventory not updated: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
});
}
@ -87,16 +106,19 @@ define(function () {
}).result.then(function (v) {
inventory.inventory = v;
$http.put(Project.getURL() + '/inventory/' + inventory.id, inventory)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Inventory not updated: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.getKeys = function (cb) {
if (typeof cb != 'function') cb = function () {}
if (typeof cb != 'function') {
cb = function () {};
}
$http.get(Project.getURL() + '/keys?type=ssh').then(function (keys) {
cb(keys.data);

View File

@ -7,31 +7,47 @@ define(function () {
}
$scope.remove = function (key) {
$http.delete(Project.getURL() + '/keys/' + key.id).then(function () {
$scope.reload();
}).catch(function (response) {
var d = response.data;
$http.delete(Project.getURL() + '/keys/' + key.id)
.then(function () {
$scope.reload();
})
.catch(function (response) {
var d = response.data;
if (!(d && d.inUse)) {
swal('error', 'could not delete key..', 'error');
return;
}
if (!(d && d.inUse)) {
swal('error', 'could not delete key..', 'error');
return;
}
swal({
title: 'Key in use',
text: d.error,
type: 'error',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Mark as removed'
}, function () {
$http.delete(Project.getURL() + '/keys/' + key.id + '?setRemoved=1').then(function () {
$scope.reload();
}).catch(function () {
swal('error', 'could not remove key..', 'error');
swal({
title: 'Key in use',
text: d.error,
icon: 'error',
buttons: {
cancel: true,
confirm: {
text: 'Mark as removed',
closeModel: false,
className: 'bg-danger',
}
}
}).then(function (value) {
if (!value) {
return;
}
$http.delete(Project.getURL() + '/keys/' + key.id + '?setRemoved=1')
.then(function () {
swal.stopLoading();
swal.close();
$scope.reload();
})
.catch(function () {
swal('Error', 'Could not remove key..', 'error');
});
});
});
});
}
$scope.add = function () {
@ -43,7 +59,8 @@ define(function () {
}).catch(function (response) {
swal('error', 'could not add key:' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.update = function (key) {
@ -61,12 +78,13 @@ define(function () {
}
$http.put(Project.getURL() + '/keys/' + key.id, opts.key)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'could not update key:' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.reload();

View File

@ -20,30 +20,46 @@ define(function () {
}
$scope.remove = function (repo) {
$http.delete(Project.getURL() + '/repositories/' + repo.id).then(function () {
$scope.reload();
}).then(function (response) {
var d = response.data;
if (!(d && d.templatesUse)) {
swal('error', 'could not delete repository..', 'error');
return;
}
swal({
title: 'Repository in use',
text: d.error,
type: 'error',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Mark as removed'
}, function () {
$http.delete(Project.getURL() + '/repositories/' + repo.id + '?setRemoved=1').then(function () {
$scope.reload();
}).catch(function () {
$http.delete(Project.getURL() + '/repositories/' + repo.id)
.then(function () {
$scope.reload();
})
.catch(function (response) {
var d = response.data;
if (!(d && d.templatesUse)) {
swal('error', 'could not delete repository..', 'error');
return;
}
swal({
title: 'Repository in use',
text: d.error,
icon: 'error',
buttons: {
cancel: true,
confirm: {
text: 'Mark as removed',
closeModel: false,
className: 'bg-danger',
}
}
}).then(function (value) {
if (!value) {
return;
}
$http.delete(Project.getURL() + '/repositories/' + repo.id + '?setRemoved=1')
.then(function () {
swal.stopLoading();
swal.close();
$scope.reload();
})
.catch(function () {
swal('Error', 'Could not delete repository..', 'error');
});
});
});
});
}
$scope.update = function (repo) {
@ -64,7 +80,8 @@ define(function () {
}).catch(function (response) {
swal('Error', 'Repository not updated: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.add = function () {
@ -76,12 +93,13 @@ define(function () {
scope: scope
}).result.then(function (repo) {
$http.post(Project.getURL() + '/repositories', repo.repo)
.then(function () {
$scope.reload();
}).catch(function (response) {
.then(function () {
$scope.reload();
}).catch(function (response) {
swal('Error', 'Repository not added: ' + response.status, 'error');
});
}, function () {});
}, function () {
});
}
$scope.reload();