diff --git a/.github/workflows/generate-postman-collection.yml b/.github/workflows/generate-postman-collection.yml new file mode 100644 index 00000000..3fb5bd6a --- /dev/null +++ b/.github/workflows/generate-postman-collection.yml @@ -0,0 +1,26 @@ +name: generate-postman-collection + +on: + push: + paths: + - "src/openapi.yaml" + - ".github/workflows/generate-postman-collection.yml" + branches: + - '**' + workflow_dispatch: + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Install dependencies + run: npm install -g openapi-to-postmanv2 + - name: Create tests folder + run: mkdir -p ./tests/postman + - name: Generate Postman collection + run: openapi2postmanv2 -s ./src/openapi.yaml -o ./tests/postman/collection.json --pretty diff --git a/.github/workflows/generate-sdks.yml b/.github/workflows/generate-sdks.yml new file mode 100644 index 00000000..cbed4980 --- /dev/null +++ b/.github/workflows/generate-sdks.yml @@ -0,0 +1,36 @@ +name: generate-sdks + +on: + push: + paths: + - "src/openapi.yaml" + - ".github/workflows/generate-sdks.yml" + branches: + - '**' + workflow_dispatch: + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Install dependencies + run: npm install -g @openapitools/openapi-generator-cli + - name: Validate schema + run: openapi-generator-cli validate -i ./src/openapi.yaml + - name: Generate Java client + run: openapi-generator-cli generate -i ./src/openapi.yaml --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \ + -o ./sdks/java -g java --additional-properties=dateLibrary=java8,java8=true,optionalProjectFile=false,optionalAssemblyInfo=false + - name: Generate .NET Core client + run: openapi-generator-cli generate -i ./src/openapi.yaml --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \ + -o ./sdks/netcore -g csharp-netcore --additional-properties=optionalProjectFile=false,optionalAssemblyInfo=false + - name: Generate .NET Full Framework client + run: openapi-generator-cli generate -i ./src/openapi.yaml --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \ + -o ./sdks/net -g csharp --additional-properties=optionalProjectFile=false,optionalAssemblyInfo=false + - name: Generate Python client + run: openapi-generator-cli generate -i ./src/openapi.yaml --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \ + -o ./sdks/python -g python --additional-properties=optionalProjectFile=false,optionalAssemblyInfo=false+ \ No newline at end of file diff --git a/.github/workflows/lint-oas.yml b/.github/workflows/lint-oas.yml new file mode 100644 index 00000000..b64a684a --- /dev/null +++ b/.github/workflows/lint-oas.yml @@ -0,0 +1,24 @@ +name: lint-oas + +on: + push: + paths: + - src/openapi.yaml + - .github/workflows/lint-oas.yml + branches: + - '**' + workflow_dispatch: + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js + uses: actions/setup-node@v1 + with: + node-version: '12' + - name: Install spectral + run: npm install -g @stoplight/spectral + - name: Run OAS linter + run: spectral lint ./src/openapi.yaml \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6d1b9216..0cbe7277 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,8 @@ src/objecttypes/static/css/**/*.css.map src/objecttypes/static/fonts/ src/objecttypes/static/js/ + +# Statics generated by Workflows +/tests/postman +/sdks/ +openapitools.json diff --git a/Dockerfile b/Dockerfile index b39593f9..a6e96b02 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,85 +1,58 @@ -# This is a multi-stage build file, which means a stage is used to build -# the backend (dependencies), the frontend stack and a final production -# stage re-using assets from the build stages. This keeps the final production -# image minimal in size. - -# Stage 1 - Backend build environment -# includes compilers and build tooling to create the environment -FROM python:3.7-buster AS backend-build +# Stage 1 - Compile needed python dependencies +FROM python:3.7-buster AS build RUN apt-get update && apt-get install -y --no-install-recommends \ libpq-dev \ && rm -rf /var/lib/apt/lists/* WORKDIR /app -RUN mkdir /app/src -# Ensure we use the latest version of pip -RUN pip install pip setuptools -U COPY ./requirements /app/requirements +RUN pip install pip setuptools -U RUN pip install -r requirements/production.txt -# Stage 2 - Install frontend deps and build assets -FROM node:13-buster AS frontend-build - -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - && rm -rf /var/lib/apt/lists/* +# Stage 2 - build frontend +FROM mhart/alpine-node:10 AS frontend-build WORKDIR /app -# copy configuration/build files -COPY ./build /app/build/ -COPY ./*.json ./*.js ./.babelrc /app/ - -# install WITH dev tooling +COPY ./*.json /app/ RUN npm ci -# copy source code -COPY ./src /app/src +COPY ./gulpfile.js ./webpack.config.js ./.babelrc /app/ +COPY ./build /app/build/ -# build frontend +COPY src/objecttypes/sass/ /app/src/objecttypes/sass/ +COPY src/objecttypes/js/ /app/src/objecttypes/js/ RUN npm run build -# Stage 3 - Build docker image suitable for production -FROM python:3.7-buster +# Stage 3 - Build docker image suitable for execution and deployment +FROM python:3.7-buster AS production # Stage 3.1 - Set up the needed production dependencies # install all the dependencies for GeoDjango RUN apt-get update && apt-get install -y --no-install-recommends \ - procps \ - vim \ postgresql-client \ - # lxml deps - # libxslt \ && rm -rf /var/lib/apt/lists/* +COPY --from=build /usr/local/lib/python3.7 /usr/local/lib/python3.7 +COPY --from=build /usr/local/bin/uwsgi /usr/local/bin/uwsgi + +# Stage 3.2 - Copy source code WORKDIR /app COPY ./bin/docker_start.sh /start.sh -RUN mkdir /app/log -RUN mkdir /app/media - -# copy backend build deps -COPY --from=backend-build /usr/local/lib/python3.7 /usr/local/lib/python3.7 -COPY --from=backend-build /usr/local/bin/uwsgi /usr/local/bin/uwsgi -COPY --from=backend-build /app/src/ /app/src/ +RUN mkdir /app/log /app/config -# copy frontend build statics -COPY --from=frontend-build /app/src/objecttypes/static /app/src/objecttypes/static - -# copy source code +COPY --from=frontend-build /app/src/objecttypes/static/css /app/src/objecttypes/static/css +COPY --from=frontend-build /app/src/objecttypes/static/js /app/src/objecttypes/static/js COPY ./src /app/src - -RUN useradd -M -u 1000 maykin -RUN chown -R maykin /app - -# drop privileges -USER maykin - ARG COMMIT_HASH +ARG RELEASE ENV GIT_SHA=${COMMIT_HASH} +ENV RELEASE=${RELEASE} + ENV DJANGO_SETTINGS_MODULE=objecttypes.conf.docker ARG SECRET_KEY=dummy @@ -87,5 +60,10 @@ ARG SECRET_KEY=dummy # Run collectstatic, so the result is already included in the image RUN python src/manage.py collectstatic --noinput +LABEL org.label-schema.vcs-ref=$COMMIT_HASH \ + org.label-schema.vcs-url="https://github.com/maykinmedia/objecttypes-api" \ + org.label-schema.version=$RELEASE \ + org.label-schema.name="Objecttypes API" + EXPOSE 8000 -CMD ["/start.sh"] +CMD ["/start.sh"] \ No newline at end of file diff --git a/INSTALL.rst b/INSTALL.rst index 5f7a945d..6ef3f245 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -18,7 +18,7 @@ Prerequisites You need the following libraries and/or programs: -* `Python`_ 3.6 or above +* `Python`_ 3.7 or above * Python `Virtualenv`_ and `Pip`_ * `PostgreSQL`_ 10 or above * `Node.js`_ @@ -44,7 +44,7 @@ development machine. .. code-block:: bash - $ git clone git@github.com:maykinmedia/objecttypes.git + $ git clone git@github.com:maykinmedia/objecttypes-api.git $ cd objecttypes 3. Install all required libraries. @@ -169,7 +169,7 @@ The easiest way to get the project started is by using `Docker Compose`_. .. code-block:: bash - $ git clone git@github.com:maykinmedia/objecttypes.git + $ git clone git@github.com:maykinmedia/objecttypes-api.git Cloning into 'objecttypes'... ... @@ -180,8 +180,8 @@ The easiest way to get the project started is by using `Docker Compose`_. .. code-block:: bash $ docker-compose up -d - Starting objecttypes_db_1 ... done - Starting objecttypes_web_1 ... done + Starting objecttypes-api_db_1 ... done + Starting objecttypes-api_web_1 ... done It can take a while before everything is done. Even after starting the web container, the database might still be migrating. You can always check the @@ -189,19 +189,19 @@ The easiest way to get the project started is by using `Docker Compose`_. .. code-block:: bash - $ docker logs -f objecttypes_web_1 + $ docker logs -f objecttypes-api_web_1 3. Create an admin user and load initial data. If different container names are shown above, use the container name ending with ``_web_1``: .. code-block:: bash - $ docker exec -it objecttypes_web_1 /app/src/manage.py createsuperuser + $ docker exec -it objecttypes-api_web_1 /app/src/manage.py createsuperuser Username: admin ... Superuser created successfully. - $ docker exec -it objecttypes_web_1 /app/src/manage.py loaddata admin_index groups + $ docker exec -it objecttypes-api_web_1 /app/src/manage.py loaddata admin_index groups Installed 5 object(s) from 2 fixture(s) 4. Point your browser to ``http://localhost:8000/`` to access the project's @@ -247,59 +247,6 @@ all settings. $ docker exec -it objecttypes /app/src/manage.py createsuperuser -Building and publishing the image ---------------------------------- - -Using ``bin/release-docker-image``, you can easily build and tag the image. - -The script is based on git branches and tags - if you're on the ``master`` -branch and the current ``HEAD`` is tagged, the tag will be used as -``RELEASE_TAG`` and the image will be pushed. If you want to push the image -without a git tag, you can use the ``RELEASE_TAG`` envvar. - -The image will only be pushed if the ``JOB_NAME`` envvar is set. The image -will always be built, even if no envvar is set. The default release tag is -``latest``. - -Example usage: - -.. code-block:: bash - - JOB_NAME=publish RELEASE_TAG=dev ./bin/release-docker-image.sh - - -Staging and production -====================== - -Ansible is used to deploy test, staging and production servers. It is assumed -the target machine has a clean `Debian`_ installation. - -1. Make sure you have `Ansible`_ installed (globally or in the virtual - environment): - - .. code-block:: bash - - $ pip install ansible - -2. Navigate to the project directory, and install the Maykin deployment - submodule if you haven't already: - - .. code-block:: bash - - $ git submodule update --init - -3. Run the Ansible playbook to provision a clean Debian machine: - - .. code-block:: bash - - $ cd deployment - $ ansible-playbook .yml - -For more information, see the ``README`` file in the deployment directory. - -.. _Debian: https://www.debian.org/ -.. _Ansible: https://pypi.org/project/ansible/ - Settings ======== diff --git a/README.NL.rst b/README.NL.rst index 7d204f84..346152c9 100644 --- a/README.NL.rst +++ b/README.NL.rst @@ -5,9 +5,8 @@ Objecttypen API :Version: 0.1.0 :Source: https://github.com/maykinmedia/objecttypes-api :Keywords: objecten, assets, zaakobjecten -:PythonVersion: 3.7 -|build-status| |docs| |coverage| |black| |docker| +|docs| API om object definities te beheren. (`English version`_) @@ -27,9 +26,50 @@ Objecttypen API draaien en zo landelijke als lokale definities van objecten hanteren. +API specificatie +================ + +|lint-oas| |generate-sdks| |generate-postman-collection| + +============== ============== ============================= +Versie Release datum API specificatie +============== ============== ============================= +1.0.0-alpha n/a `ReDoc `_, + `Swagger `_ +============== ============== ============================= + +Zie: `Alle versies en wijzigingen `_ + + +Referentie implementatie +======================== + +|build-status| |coverage| |black| |docker| |python-versions| + +De referentie implementatie toont de API in actie en kan gebruikt worden voor +test en demonstratie doeleinden. De referentie implementatie is open source, +goed getest en beschikbaar als Docker image. + +Quickstart +---------- + +1. Download en start de Objecttypen API: + + .. code:: bash + + $ wget https://raw.githubusercontent.com/maykinmedia/objecttypes-api/master/docker-compose-quickstart.yml -O docker-compose.yml + $ docker-compose up -d + $ docker-compose exec web src/manage.py createsuperuser + +2. In de browser, navigeer naar ``http://localhost:8001/`` om de admin en de + API te benaderen. + + Links ===== +* `Documentatie `_ +* `Docker image `_ * `Issues `_ * `Code `_ * `Community `_ @@ -64,7 +104,24 @@ Licensed under the EUPL_ :target: https://codecov.io/gh/maykinmedia/objecttypes-api .. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :alt: Code style :target: https://github.com/psf/black .. |docker| image:: https://images.microbadger.com/badges/image/maykinmedia/objecttypes-api.svg - :target: https://microbadger.com/images/maykinmedia/objecttypes-api + :alt: Docker image + :target: https://hub.docker.com/r/maykinmedia/objecttypes-api + +.. |python-versions| image:: https://img.shields.io/badge/python-3.7%2B-blue.svg + :alt: Supported Python version + +.. |lint-oas| image:: https://github.com/maykinmedia/objecttypes-api/workflows/lint-oas/badge.svg + :alt: Lint OAS + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Alint-oas + +.. |generate-sdks| image:: https://github.com/maykinmedia/objecttypes-api/workflows/generate-sdks/badge.svg + :alt: Generate SDKs + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Agenerate-sdks + +.. |generate-postman-collection| image:: https://github.com/maykinmedia/objecttypes-api/workflows/generate-postman-collection/badge.svg + :alt: Generate Postman collection + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Agenerate-postman-collection diff --git a/README.rst b/README.rst index f9a4030b..f602f986 100644 --- a/README.rst +++ b/README.rst @@ -5,9 +5,8 @@ Objecttypes API :Version: 0.1.0 :Source: https://github.com/maykinmedia/objecttypes-api :Keywords: objects, assets, zaakobjecten -:PythonVersion: 3.7 -|build-status| |docs| |coverage| |black| |docker| +|docs| API to manage object definitions. (`Nederlandse versie`_) @@ -26,9 +25,50 @@ This national Objecttypes API is required for registering objects in local both national and local definitions of objects. +API specification +================= + +|lint-oas| |generate-sdks| |generate-postman-collection| + +============== ============== ============================= +Version Release date API specification +============== ============== ============================= +1.0.0-alpha n/a `ReDoc `_, + `Swagger `_ +============== ============== ============================= + +See: `All versions and changes `_ + + +Reference implementation +======================== + +|build-status| |coverage| |black| |docker| |python-versions| + +The reference implementation is used to demonstrate the API in action and can +be used for test and demo purposes. The reference implementation is open source, +well tested and available as Docker image. + +Quickstart +---------- + +1. Download and run the Objecttypes API: + + .. code:: bash + + $ wget https://raw.githubusercontent.com/maykinmedia/objecttypes-api/master/docker-compose-quickstart.yml -O docker-compose.yml + $ docker-compose up -d + $ docker-compose exec web src/manage.py createsuperuser + +2. In the browser, navigate to ``http://localhost:8001/`` to access the admin + and the API. + + References ========== +* `Documentation `_ +* `Docker image `_ * `Issues `_ * `Code `_ * `Community `_ @@ -63,7 +103,24 @@ Licensed under the EUPL_ :target: https://codecov.io/gh/maykinmedia/objecttypes-api .. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :alt: Code style :target: https://github.com/psf/black .. |docker| image:: https://images.microbadger.com/badges/image/maykinmedia/objecttypes-api.svg - :target: https://microbadger.com/images/maykinmedia/objecttypes-api + :alt: Docker image + :target: https://hub.docker.com/r/maykinmedia/objecttypes-api + +.. |python-versions| image:: https://img.shields.io/badge/python-3.7%2B-blue.svg + :alt: Supported Python version + +.. |lint-oas| image:: https://github.com/maykinmedia/objecttypes-api/workflows/lint-oas/badge.svg + :alt: Lint OAS + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Alint-oas + +.. |generate-sdks| image:: https://github.com/maykinmedia/objecttypes-api/workflows/generate-sdks/badge.svg + :alt: Generate SDKs + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Agenerate-sdks + +.. |generate-postman-collection| image:: https://github.com/maykinmedia/objecttypes-api/workflows/generate-postman-collection/badge.svg + :alt: Generate Postman collection + :target: https://github.com/maykinmedia/objecttypes-api/actions?query=workflow%3Agenerate-postman-collection diff --git a/bin/docker_start.sh b/bin/docker_start.sh index 39b23254..2516c4dd 100755 --- a/bin/docker_start.sh +++ b/bin/docker_start.sh @@ -10,8 +10,10 @@ export PGPORT=${DB_PORT:-5432} fixtures_dir=${FIXTURES_DIR:-/app/fixtures} uwsgi_port=${UWSGI_PORT:-8000} -uwsgi_processes=${UWSGI_PROCESSES:-4} -uwsgi_threads=${UWSGI_THREADS:-1} +uwsgi_processes=${UWSGI_PROCESSES:-2} +uwsgi_threads=${UWSGI_THREADS:-2} + +mountpoint=${SUBPATH:-/} until pg_isready; do >&2 echo "Waiting for database connection..." @@ -24,18 +26,28 @@ done >&2 echo "Apply database migrations" python src/manage.py migrate +# Load any JSON fixtures present +if [ -d $fixtures_dir ]; then + echo "Loading fixtures from $fixtures_dir" + + for fixture in $(ls "$fixtures_dir/"*.json) + do + echo "Loading fixture $fixture" + python src/manage.py loaddata $fixture + done +fi + # Start server >&2 echo "Starting server" uwsgi \ --http :$uwsgi_port \ --http-keepalive \ - --module objecttypes.wsgi \ + --manage-script-name \ + --mount $mountpoint=objecttypes.wsgi:application \ --static-map /static=/app/static \ --static-map /media=/app/media \ --chdir src \ --enable-threads \ --processes $uwsgi_processes \ --threads $uwsgi_threads \ - --post-buffering=8192 \ - --buffer-size=65535 - # processes & threads are needed for concurrency without nginx sitting inbetween + --buffer-size=65535 \ No newline at end of file diff --git a/bin/live2staging.sh b/bin/live2staging.sh deleted file mode 100644 index 10cc52e1..00000000 --- a/bin/live2staging.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -# This script should be run on staging. -source live2staging_settings.sh - -# Script starts here -TMP_FILE="$PGSQL_PROD_DB_NAME-livedb.sql" -TMP_MEDIA_FILE="$PGSQL_PROD_DB_NAME-media.tgz" - -if [ -f $TMP_FILE ]; then - echo -n "Create new dump? [y/n] " - read -n 1 yesno -else - yesno="y" -fi -echo - -if [ "$yesno" == "y" ]; then - echo "Creating dump of production database, please wait..." - - PGSQLDUMP_PROD_CMD_ARGS="--dbname=postgresql://$PGSQL_PROD_USERNAME:$PGSQL_PROD_PASSWORD@127.0.0.1:5432/$PGSQL_PROD_DB_NAME " - PGSQLDUMP_PROD_CMD="pg_dump $PGSQLDUMP_PROD_CMD_ARGS > /srv/sites/$TMP_FILE" - - ssh $PGSQL_PROD_HOST "$PGSQLDUMP_PROD_CMD" - scp $PGSQL_PROD_HOST:/srv/sites/$TMP_FILE $TMP_FILE -fi - -echo -n "Continue loading database? [y/n] " -read -n 1 cont -if [ "$cont" == "n" ]; then - echo - exit -fi -echo - -sudo supervisorctl stop $SUPERVISOR_GROUP:* -sudo service cron stop - -echo "Loading dump of production database into staging, please wait..." -sudo su postgres --command="dropdb $PGSQL_STAGING_DB_NAME" -sudo su postgres --command="createdb $PGSQL_STAGING_DB_NAME --owner=$PGSQL_STAGING_USERNAME" -PGSQL_STAGING_CMD="psql -q --dbname=postgresql://$PGSQL_STAGING_USERNAME:$PGSQL_STAGING_PASSWORD@127.0.0.1:5432/$PGSQL_STAGING_DB_NAME " -$PGSQL_STAGING_CMD < $TMP_FILE - -echo "Modifying data on staging to work with production data..." -$PGSQL_STAGING_CMD < $PWD/live2staging_postimport.sql - -echo "Copying media files from production to staging..." -rsync -au $PGSQL_PROD_HOST:$PROD_MEDIA_PATH/ $STAGING_MEDIA_PATH/ - -sudo chmod -R g+rw $STAGING_PROJECT_PATH - -cd $STAGING_PROJECT_PATH -source env/bin/activate - -env/bin/python src/manage.py migrate -env/bin/python src/manage.py locate_translation_files -sudo service cron start -sudo supervisorctl start $SUPERVISOR_GROUP:* - -cd $PWD - -NOW=$(date +"%Y-%m-%d") -FILE="$PGSQL_PROD_DB_NAME-live2staging-$NOW.sql" - -if [ "$yesno" == "y" ]; then - echo "Storing dump as $FILE..." - cp "$PWD/$TMP_FILE" "$FILE" - gzip $FILE -fi diff --git a/bin/live2staging_postimport.sql b/bin/live2staging_postimport.sql deleted file mode 100644 index 84d23301..00000000 --- a/bin/live2staging_postimport.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE accounts_user SET email=CONCAT('notify+', REPLACE(email,'@','__at__'), '@maykin.nl'), password='pbkdf2_sha256$12000$pZphUuHkCDke$x8KlvmVInqS1ru9sGZ1tkDStNkMh1xYU1VaG6SHtHMw='; diff --git a/bin/live2staging_settings.sh b/bin/live2staging_settings.sh deleted file mode 100644 index 6d2d092a..00000000 --- a/bin/live2staging_settings.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -# Settings for live2staging.sh -PGSQL_STAGING_DB_NAME="" -PGSQL_STAGING_USERNAME="" -PGSQL_STAGING_PASSWORD="" - -PGSQL_PROD_DB_NAME="" -PGSQL_PROD_USERNAME="" -PGSQL_PROD_PASSWORD="" - -PGSQL_PROD_HOST="" # Example: john@server.nl - -# No trailing slash -PROD_MEDIA_PATH="" -STAGING_PROJECT_PATH="" -STAGING_MEDIA_PATH="$STAGING_PROJECT_PATH/media" - -SUPERVISOR_GROUP="" diff --git a/bin/release_docker_image.sh b/bin/release_docker_image.sh deleted file mode 100755 index 0ce84027..00000000 --- a/bin/release_docker_image.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -set -e # exit on error -set -x # echo commands - -CONTAINER_REPO=maykinmedia/objecttypes - -git_tag=$(git tag --points-at HEAD) &>/dev/null -git_branch=$(git rev-parse --abbrev-ref HEAD) - - -build_image() { - tag=$1 - docker build \ - --target production \ - -t ${CONTAINER_REPO}:$tag \ - -f Dockerfile . -} - -get_release_tag() { - if [[ -n "$git_tag" ]]; then - release_tag=$git_tag - else - release_tag=${RELEASE_TAG:-latest} - fi - echo $release_tag -} - -push_image() { - # JOB_NAME is set by Jenkins - # only push the image if running in CI - release_tag=$1 - if [[ -n "$JOB_NAME" ]]; then - docker push ${CONTAINER_REPO}:$release_tag - - # if this is a tag, and this is master -> push latest as well - if [[ -n "$git_tag" && $git_branch -eq "master" ]]; then - build_image latest - docker push ${CONTAINER_REPO}:latest - fi - - write_deploy_params - else - echo "Not pushing image, set the JOB_NAME envvar to push after building" - fi -} - -write_deploy_params() { - # if on jenkins AND it's a tagged release -> prepare deployment - if [[ -n "$JENKINS_URL" && -n "$git_tag" ]]; then - echo " -VERSION=${git_tag} -" > deployment-parameters - fi -} - - -if [[ -n "$git_tag" ]]; then - echo "Building image for git tag $git_tag" -fi - -release_tag=$(get_release_tag) -build_image $release_tag -push_image $release_tag diff --git a/docker-compose-quickstart.yml b/docker-compose-quickstart.yml new file mode 100644 index 00000000..63d908d9 --- /dev/null +++ b/docker-compose-quickstart.yml @@ -0,0 +1,18 @@ +version: '3' + +services: + db: + image: postgres + environment: + - POSTGRES_USER=${DB_USER:-objecttypes} + - POSTGRES_PASSWORD=${DB_PASSWORD:-objecttypes} + + web: + image: maykinmedia/objecttypes-api:latest + environment: + - DJANGO_SETTINGS_MODULE=objecttypes.conf.docker + - SECRET_KEY=${SECRET_KEY:-fgv=c0hz&tl*8*3m3893@m+1pstrvidc9e^5@fpspmg%cy$15d} + ports: + - 8001:8000 + depends_on: + - db diff --git a/docker-compose.yml b/docker-compose.yml index 530b1cb8..3caf89f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -# Inspired by https://docs.docker.com/compose/django/ version: '3' services: @@ -6,10 +5,9 @@ services: # NOTE: No persistance storage configured. # See: https://hub.docker.com/_/postgres/ image: postgres - # NOTE: this works for bitnami, not sure if this works for regular - # postgres image - volumes: - - ./docker-init-db.sql:/docker-entrypoint-initdb.d/init_db.sql + environment: + - POSTGRES_USER=${DB_USER:-objecttypes} + - POSTGRES_PASSWORD=${DB_PASSWORD:-objecttypes} web: build: . diff --git a/docker-init-db.sql b/docker-init-db.sql deleted file mode 100644 index 4ce7c10f..00000000 --- a/docker-init-db.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE USER objecttypes; -CREATE DATABASE objecttypes; -GRANT ALL PRIVILEGES ON DATABASE objecttypes TO objecttypes; - diff --git a/src/objecttypes/api/urls.py b/src/objecttypes/api/urls.py index f6a15e70..1c108607 100644 --- a/src/objecttypes/api/urls.py +++ b/src/objecttypes/api/urls.py @@ -6,7 +6,7 @@ from .views import ObjectTypeViewSet -router = routers.DefaultRouter() +router = routers.DefaultRouter(trailing_slash=False) router.register(r"objecttypes", ObjectTypeViewSet) diff --git a/src/objecttypes/conf/docker.py b/src/objecttypes/conf/docker.py index df5e7dcb..6a617b50 100644 --- a/src/objecttypes/conf/docker.py +++ b/src/objecttypes/conf/docker.py @@ -2,10 +2,10 @@ from django.core.exceptions import ImproperlyConfigured -os.environ.setdefault("DB_USER", os.getenv("DATABASE_USER", "postgres")) -os.environ.setdefault("DB_NAME", os.getenv("DATABASE_NAME", "postgres")) -os.environ.setdefault("DB_PASSWORD", os.getenv("DATABASE_PASSWORD", "")) -os.environ.setdefault("DB_HOST", os.getenv("DATABASE_HOST", "db")) +os.environ.setdefault("DB_USER", os.getenv("DB_USER", "objecttypes")) +os.environ.setdefault("DB_NAME", os.getenv("DB_NAME", "objecttypes")) +os.environ.setdefault("DB_PASSWORD", os.getenv("DB_PASSWORD", "objecttypes")) +os.environ.setdefault("DB_HOST", os.getenv("DB_HOST", "db")) from .base import * # noqa isort:skip diff --git a/src/openapi.yaml b/src/openapi.yaml index 9e2914f7..5c75b2f5 100644 --- a/src/openapi.yaml +++ b/src/openapi.yaml @@ -6,7 +6,7 @@ info: security: - Token: [] paths: - /objecttypes/: + /objecttypes: get: operationId: objecttype_list description: '' @@ -144,7 +144,7 @@ paths: tags: - objecttypes parameters: [] - /objecttypes/{uuid}/: + /objecttypes/{uuid}: get: operationId: objecttype_read description: '' @@ -159,12 +159,12 @@ paths: \ voor meer informatie." required: false examples: - oneValue: - summary: "E\xE9n ETag-waarde" - value: '"79054025255fb1a26e4bc422aef54eb4"' multipleValues: summary: Meerdere ETag-waardes value: '"79054025255fb1a26e4bc422aef54eb4", "e4d909c290d0fb1ca068ffaddf22cbd0"' + oneValue: + summary: "E\xE9n ETag-waarde" + value: '"79054025255fb1a26e4bc422aef54eb4"' schema: type: string responses: @@ -305,16 +305,16 @@ paths: type: string format: uuid tags: -- name: '' +- name: objecttypes description: '' servers: - url: https://example.com/api/v1 components: securitySchemes: Token: - type: apiKey - name: Authorization in: header + name: Authorization + type: apiKey schemas: ObjectVersion: type: object diff --git a/src/swagger2.0.json b/src/swagger2.0.json index d0d40da7..9f4d361d 100755 --- a/src/swagger2.0.json +++ b/src/swagger2.0.json @@ -18,9 +18,9 @@ ], "securityDefinitions": { "Token": { - "type": "apiKey", + "in": "header", "name": "Authorization", - "in": "header" + "type": "apiKey" } }, "security": [ @@ -29,7 +29,7 @@ } ], "paths": { - "/objecttypes/": { + "/objecttypes": { "get": { "operationId": "objecttype_list", "description": "", @@ -193,7 +193,7 @@ }, "parameters": [] }, - "/objecttypes/{uuid}/": { + "/objecttypes/{uuid}": { "get": { "operationId": "objecttype_read", "description": "", @@ -205,13 +205,13 @@ "required": false, "type": "string", "examples": { - "oneValue": { - "summary": "E\u00e9n ETag-waarde", - "value": "\"79054025255fb1a26e4bc422aef54eb4\"" - }, "multipleValues": { "summary": "Meerdere ETag-waardes", "value": "\"79054025255fb1a26e4bc422aef54eb4\", \"e4d909c290d0fb1ca068ffaddf22cbd0\"" + }, + "oneValue": { + "summary": "E\u00e9n ETag-waarde", + "value": "\"79054025255fb1a26e4bc422aef54eb4\"" } } } @@ -611,7 +611,7 @@ }, "tags": [ { - "name": "", + "name": "objecttypes", "description": "" } ]