diff --git a/.gitignore b/.gitignore index 8dfc15d3..00e79017 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ *.iml molecule/**/.molecule/ +molecule/**/__pycache__/ diff --git a/.travis.yml b/.travis.yml index 4be0ea7d..f3790c35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,13 @@ sudo: required language: python +cache: + pip: true + directories: + - molecule/default/.molecule/nexus-downloads/ services: - docker -before_install: - - sudo apt-get update - - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce - - sudo apt-get -y install groovy install: - - pip install molecule - - pip install docker-py + - pip install -r requirements.txt script: - - ./tests/run_all_tests.sh \ No newline at end of file + - ./tests/test_molecule.sh diff --git a/.yamllint b/.yamllint index 6c21dbdb..6f4b8d4e 100644 --- a/.yamllint +++ b/.yamllint @@ -1,17 +1,43 @@ +--- extends: default rules: - braces: - max-spaces-inside: 1 + indentation: + spaces: 2 + check-multi-line-strings: true + line-length: + max: 250 level: warning + document-start: + present: true + level: error + key-duplicates: enable + trailing-spaces: enable + hyphens: + max-spaces-after: 1 + level: error + empty-lines: + max: 2 + max-start: 0 + max-end: 0 + level: error + commas: + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + level: error + colons: + max-spaces-before: 0 + max-spaces-after: 1 + level: error brackets: - max-spaces-inside: 1 - level: warning - line-length: disable + min-spaces-inside: 0 + max-spaces-inside: 0 + level: error + braces: + min-spaces-inside: 0 + max-spaces-inside: 0 + level: error truthy: disable - empty-lines: - level: warning - indentation: - level: warning - indent-sequences: consistent new-line-at-end-of-file: disable + comments-indentation: enable diff --git a/README.md b/README.md index 54f27b51..19573404 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,43 @@ # Ansible Role: Nexus 3 OSS -This role installs and configures Nexus Repository Manager OSS version 3.x. +This role installs and configures Nexus Repository Manager OSS version 3.x. All configuration can be updated by re-running the role, except forthe [blobstores](https://books.sonatype.com/nexus-book/3.0/reference/admin.html#admin-repository-blobstores)-related settings, which are immutable in nexus. +## Table of Contents +(Toc created with [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)) + +* [History / Credits](#history--credits) +* [Requirements](#requirements) +* [Role Variables](#role-variables) + * [General variables](#general-variables) + * [Download dir for nexus package](#download-dir-for-nexus-package) + * [Nexus port and context path](#nexus-port-and-context-path) + * [Nexus OS user and group](#nexus-os-user-and-group) + * [Nexus instance directories](#nexus-instance-directories) + * [Admin password](#admin-password) + * [Default anonymous access](#default-anonymous-access) + * [Public hostname](#public-hostname) + * [Branding capabalities](#branding-capabalities) + * [Reverse proxy setup](#reverse-proxy-setup) + * [LDAP configuration](#ldap-configuration) + * [Privileges, roles and users](#privileges-roles-and-users) + * [Blobstores and repositories](#blobstores-and-repositories) + * [Scheduled tasks](#scheduled-tasks) + * [Backups](#backups) + * [Restore procedure](#restore-procedure) + * [Current limitations:](#current-limitations) +* [Dependencies](#dependencies) +* [Example Playbook](#example-playbook) +* [Development, Contribution and Testing](#development-contribution-and-testing) + * [Contributions](#contributions) + * [Testing](#testing) + * [Groovy syntax](#groovy-syntax) + * [Full role testing with molecule](#full-role-testing-with-molecule) + * [Testing everything](#testing-everything) +* [License](#license) +* [Author Information](#author-information) + ## History / Credits This role is a fork of [ansible-nexus3-oss](https://github.com/savoirfairelinux/ansible-nexus3-oss) by [@savoirfairelinux](https://github.com/savoirfairelinux) after they announced end of maintenance. @@ -15,31 +49,39 @@ We would like to thank the original authors for the work done. ## Requirements +- Minimum ansible version 2.2 (see meta/main.yml). Due to the use of the ansible [synchronize module](http://docs.ansible.com/ansible/latest/synchronize_module.html) you will need _version 2.3 for tests with molecule (using docker containers)_. - This role is tested through travis CI only on CentOS 7 + Ubuntu 16.04 (Xenial) for time being -- Oracle Java 8 (mandatory) -- Apache HTTPD (optional, used to setup a SSL reverse-proxy) +- Java 8 (mandatory) + - Oracle Java 8 is the official supported platform by Sonatype + - openjdk8 is know to work and is used for deployment test on travis on the corresponding platform docker images. + - For more information see [nexus3 system requirements](https://help.sonatype.com/display/NXRM3/System+Requirements) +- Apache HTTPD (optional) + - Used to setup a SSL reverse-proxy + - The following modules must be enabled in your configuration: mod_ssl, mod_rewrite, mod_proxy, mod_headers. (see [Dependencies](#dependencies) section below for matching roles on galaxy) ## Role Variables - Ansible variables, along with the default values (see `default/main.yml`) : +### General variables ```yaml - nexus_version: '3.1.0-04' + nexus_version: '3.6.1-02' nexus_timezone: 'UTC' nexus_package: "nexus-{{ nexus_version }}-unix.tar.gz" ``` The nexus version and package to install, see available versions at https://www.sonatype.com/download-oss-sonatype . `nexus_timezone` is a Java Timezone name and can be useful in combination with `nexus_scheduled_tasks` cron expressions below. +### Download dir for nexus package ```yaml nexus_download_dir: '/tmp' ``` Directory on target where the nexus package will be downloaded. +### Nexus port and context path ```yaml nexus_default_port: 8081 nexus_default_context_path: '/' @@ -47,6 +89,7 @@ Directory on target where the nexus package will be downloaded. Port and context path of the java nexus process. `nexus_default_context_path` has to keep the trailing slash when set, for ex. : `nexus_default_context_path: '/nexus/'`. +### Nexus OS user and group ```yaml nexus_os_group: 'nexus' nexus_os_user: 'nexus' @@ -54,6 +97,7 @@ Port and context path of the java nexus process. `nexus_default_context_path` ha User and group used to own the nexus files and run the service, those will be created by the role if absent. +### Nexus instance directories ```yaml nexus_installation_dir: '/opt' nexus_data_dir: '/var/nexus' @@ -62,24 +106,29 @@ User and group used to own the nexus files and run the service, those will be cr Nexus directories, `nexus_installation_dir` contains the installed executable(s), `nexus_data_dir` contains all configuration, repositories and uploaded artifacts. Note: custom blobstores paths outside of `nexus_data_dir` can be configured, see `nexus_blobstores` below. +### Admin password ```yaml nexus_admin_password: 'changeme' ``` The 'admin' account password to setup. Note : admin password change subsequent to first-time provisioning/install is *not implemented* by this role yet. +**It is strongly advised that you do not keep your password in clear text in you playbook and include it from a separate ansible-vault encrypted files (loaded with include_vars for example)** +### Default anonymous access ```yaml nexus_anonymous_access: false ``` Allow [anonymous access](https://books.sonatype.com/nexus-book/3.0/reference/security.html#anonymous) to nexus. +### Public hostname ```yaml public_hostname: 'nexus.vm' ``` The fully qualified domain name under which the nexus instance will be accessible to its clients. +### Branding capabalities ```yaml nexus_branding_header: "" nexus_branding_footer: "Last provisionned {{ ansible_date_time.iso8601 }}" @@ -87,6 +136,7 @@ The fully qualified domain name under which the nexus instance will be accessibl Header and footer branding, those can contain HTML. +### Reverse proxy setup ```yaml httpd_setup_enable: false httpd_ssl_certificate_file: 'files/nexus.vm.crt' @@ -111,6 +161,7 @@ Use already existing SSL certificates on the server file system for the https re Set httpd default admin email address +### LDAP configuration ```yaml ldap_connections: [] ``` @@ -200,6 +251,7 @@ Example LDAP config for simple authentication (using a DSA account) + groups map ldap_group_subtree: false ``` +### Privileges, roles and users ```yaml nexus_privileges: - name: all-repos-read # used as key to update a privilege @@ -249,6 +301,7 @@ Local (non-LDAP) users/accounts to create in nexus, items go as follow : - developers # role ID ``` +### Blobstores and repositories ```yaml nexus_delete_default_repos: false ``` @@ -270,18 +323,6 @@ Delete the default blobstore from the nexus install initial default configuratio [Blobstores](https://books.sonatype.com/nexus-book/3.0/reference/admin.html#admin-repository-blobstores) to create. A blobstore path and a repository blobstore cannot be updated after initial creation (any update here will be ignored on re-provisionning). -```yaml - nexus_scheduled_tasks: [] - # example task to compact blobstore : - # - name: compact-blobstore - # cron: '0 0 22 * * ?' - # typeId: blobstore.compact - # taskProperties: - # blobstoreName: 'default' # all task attributes are stored as strings by nexus internally -``` - -[Scheduled tasks](https://books.sonatype.com/nexus-book/reference3/admin.html#admin-system-tasks) to setup. `typeId` and task-specific `taskProperties` can be guessed either from the java type hierarchy of `org.sonatype.nexus.scheduling.TaskDescriptorSupport` or from peeking at the browser AJAX requests while manually configuring a task. - ```yaml nexus_repos_maven_proxy: - name: central @@ -328,7 +369,7 @@ All three repository types are combined with the following default values : write_policy: allow_once # allow_once or allow ``` -Docker, Pypi, Raw, Rubygems, Bower, NPM, and Git-LFS repository types: +Docker, Pypi, Raw, Rubygems, Bower, NPM, Git-LFS and yum repository types: see `defaults/main.yml` for these options: ```yaml @@ -339,13 +380,101 @@ see `defaults/main.yml` for these options: nexus_config_bower: false nexus_config_npm: false nexus_config_gitlfs: false + nexus_config_yum: false ``` These are all false unless you override them from playbook / group_var / cli, these all utilize the same mechanism as maven. +### Scheduled tasks +```yaml + nexus_scheduled_tasks: [] + # # Example task to compact blobstore : + # - name: compact-docker-blobstore + # cron: '0 0 22 * * ?' + # typeId: blobstore.compact + # task_alert_email: alerts@example.org # optional + # taskProperties: + # blobstoreName: {{ nexus_blob_names.docker.blob }} # all task attributes are stored as strings by nexus internally + # # Example task to purge maven snapshots + # - name: Purge-maven-snapshots + # cron: '0 50 23 * * ?' + # typeId: repository.maven.remove-snapshots + # task_alert_email: alerts@example.org # optional + # taskProperties: + # repositoryName: "*" # * for all repos. Change to a repository name if you only want a specific one + # minimumRetained: "2" + # snapshotRetentionDays: "2" + # gracePeriodInDays: "2" + # booleanTaskProperties: + # removeIfReleased: true + # # Example task to purge unused docker manifest and images + # - name: Purge unused docker manifests and images + # cron: '0 55 23 * * ?' + # typeId: "repository.docker.gc" + # task_alert_email: alerts@example.org # optional + # taskProperties: + # repositoryName: "*" # * for all repos. Change to a repository name if you only want a specific one + # # Example task to purge incomplete docker uploads + # - name: Purge incomplete docker uploads + # cron: '0 0 0 * * ?' + # typeId: "repository.docker.upload-purge" + # task_alert_email: alerts@example.org # optional + # taskProperties: + # age: "24" +``` + +[Scheduled tasks](https://books.sonatype.com/nexus-book/reference3/admin.html#admin-system-tasks) to setup. `typeId` and task-specific `taskProperties`/`booleanTaskProperties` can be guessed either: +* from the java type hierarchy of `org.sonatype.nexus.scheduling.TaskDescriptorSupport` +* by inspecting the task creation html form in your browser +* from peeking at the browser AJAX requests while manually configuring a task. + +**Task properties must be declared in the correct yaml block depending on their type**: +* `taskProperties` for all string properties (i.e. repository names, blobstore names, time periods...). +* `booleanTaskProperties` for all boolean properties (i.e. mainly checkboxes in nexus create task GUI). + +### Backups +```yaml + nexus_backup_configure: false + nexus_backup_cron: '* 0 21 * * ?' # See cron expressions definition in nexus create task gui + nexus_backup_dir: '/var/nexus-backup' + nexus_backup_log: '{{ nexus_backup_dir }}/nexus-backup.log' + nexus_restore_log: '{{ nexus_backup_dir }}/nexus-restore.log' +``` + +Backup will not be configured unless you switch `nexus_backup_configure` to `true`. +In this case, a scheduled script task will be configured in nexus to run every day +at time specified by `nexus_backup_cron` (defaults to 9pm). +See [the groovy template for this task](templates/backup.groovy.j2) for details. +This scheduled task is independent from the other `nexus_scheduled_tasks` you +declare in your playbook + +Note that `nexus_backup_log` must be writable by the nexus user or the backup +task will fail + +#### Restore procedure + +Run your playbook with parameter `-e nexus_restore_point=` +(e.g. 17-12-17 for 17th of December 2017) + +#### Current limitations +* Due to the initial chosen naming convention for restore points, +backups can only be ran once a day (this will be fixed in a future release - see #19). +Running more than once a day will work without errors but will: + * overwrite the last blobstore copy in the current daily backup dir + * multiply the instances of nexus db backup files in the daily backup dir + which might later confuse the restore script. +* There is no rotation for backups. All of them will be kept unless you implement +a rotation/cleanup by yourself. This might be added as an enhancement in a future release +* Blobstore copies are made directly from nexus by the script scheduled task. +This has only been tested on rather small blobstores (less than 50Go) and should +be used with caution and tested carefully on larger installations before moving +to production. In any case, you are free to implement your own backup scenario +outside of this role. + + ## Dependencies -This role requires Ansible 2.1 or higher. +This role requires Ansible 2.2 or higher. The java and httpd requirements /can/ be fulfilled with the following galaxy roles : - [ansiblebit.oracle-java](https://galaxy.ansible.com/ansiblebit/oracle-java/) @@ -354,7 +483,8 @@ The java and httpd requirements /can/ be fulfilled with the following galaxy rol ## Example Playbook ```yaml -------- + +--- - name: Nexus hosts: nexus become: yes @@ -456,11 +586,12 @@ The java and httpd requirements /can/ be fulfilled with the following galaxy rol # - { role: geerlingguy.apache, apache_create_vhosts: no, apache_mods_enabled: ["proxy_http.load", "headers.load"], apache_remove_default_vhost: true, tags: ["geerlingguy.apache"] } # RedHat/CentOS only - { role: geerlingguy.apache, apache_create_vhosts: no, apache_remove_default_vhost: true, tags: ["geerlingguy.apache"] } - - { role: savoirfairelinux.nexus3-oss, tags: ['savoirfairelinux.nexus3-oss'] } - + - { role: ansible-ThoTeam.nexus3-oss, tags: ['savoirfairelinux.nexus3-oss'] } ``` -## Development, contribution and testing +## Development, Contribution and Testing + +### Contributions All contributions to this role are welcome, either for bugfixes, new features or documentation. @@ -469,18 +600,53 @@ If you wish to contribute: - Create a branch in your own repo with a meaningfull name. We suggest the following naming convention: - feature_ for features - fix_ for bug fixes -- If starting an important feature change, open a pull request early describing what you want to do so we can discuss it if needed. +- If starting an important feature change, open a pull request early describing what you want to do so we can discuss it if needed. This will prevent you from doing a lot of hard work on a lot of code for changes that we cannot finally merge. - If there are build error on your pull request, have a look at the travis log and fix the relevant errors. Moreover, if you have time to devote for code review, merge for realeases, etc... drop an email to contact@thoteam.com to get in touch. -License -------- +### Testing + +This role includes tests and CI integration through travis. For build time sake, not all tests are run on travis. Currently, only molecule deployment tests are ran automatically on every merge request creation/upate. + +#### Groovy syntax + +This role contains a set of groovy files used to provision nexus. Those files seldom change and tests on travis require a lot of time for setup/run. So they are not run automatically. + +If you submit changes to groovy files, please run the groovy syntax check locally before pushing your changes +```bash +./tests/test_groovySyntax.sh +``` + +You will need the groovy package installed locally to run this test. + +#### Full role testing with molecule + +The role is tested on travis with [molecule](https://pypi.python.org/pypi/molecule). You can run these tests locally. The best way to achieve this is through a python virtualenv. You can find some more details in [requirements.txt](requirements.txt). +```bash +# Note: the following path should be outside the working dir +virtualenv /path/to/some/pyenv +. /path/to/some/pyenv/bin/activate +pip install -r requirements.txt +./tests/test_molecule.sh +deactivate +``` + +To speed up tests, molecule uses automated docker build images on docker hub: +- https://hub.docker.com/r/thoteam/ansible-ubuntu16.04-apache-java/ +- https://hub.docker.com/r/thoteam/ansible-centos7-apache-java/ + +#### Testing everything +As a convenience, we provide a script to run all test as once: +```bash +./tests/test_all.sh +``` + +## License GNU GPLv3 -Author Information ------------------- +## Author Information See: https://github.com/ansible-ThoTeam diff --git a/defaults/main.yml b/defaults/main.yml index 46a03333..a14bfafc 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,18 +1,18 @@ --- -nexus_version: '3.6.1-02' +nexus_version: '3.7.0-04' nexus_package: "nexus-{{ nexus_version }}-unix.tar.gz" nexus_download_dir: '/tmp' nexus_backup_dir: '/var/nexus-backup' nexus_os_group: 'nexus' nexus_os_user: 'nexus' -nexus_os_max_filedescriptors: 65536 # nexus > 3.5.x issues a warning on lower value. Next versions might not boot at all +nexus_os_max_filedescriptors: 65536 # nexus > 3.5.x issues a warning on lower value. Next versions might not boot at all nexus_installation_dir: '/opt' nexus_data_dir: '/var/nexus' -nexus_timezone: 'UTC' # java timezone +nexus_timezone: 'UTC' # java timezone nexus_tmp_dir: '/tmp/nexus' nexus_script_dir: '{{ nexus_installation_dir }}/nexus-{{ nexus_version }}/etc/scripts' -nexus_restore_log: '/var/log/nexus-restore.log' -nexus_backup_log: '/var/log/nexus-backup.log' +nexus_restore_log: '{{ nexus_backup_dir }}/nexus-restore.log' +nexus_backup_log: '{{ nexus_backup_dir }}/nexus-backup.log' # Nexus restore procedure: # run ansible-playbook example.yml -e "nexus_restore_point=(# date of choice -> %y-%m-%d #)" @@ -28,7 +28,7 @@ nexus_docker_proxy_port: 9081 nexus_docker_group_port: 9082 nexus_default_context_path: '/' -nexus_admin_password: 'changeme' # Note : admin password change subsequent to first-time install is *not implemented* yet +nexus_admin_password: 'changeme' # Note : admin password change subsequent to first-time install is *not implemented* yet nexus_anonymous_access: false public_hostname: 'nexus.vm' @@ -58,6 +58,7 @@ nexus_branding_header: "" nexus_branding_footer: "Last provisionned {{ ansible_date_time.iso8601 }}" httpd_setup_enable: false +httpd_server_name: nexus.vm httpd_ssl_certificate_file: 'files/nexus.vm.crt' httpd_ssl_certificate_key_file: 'files/nexus.vm.key' # If httpd_copy_ssl_files is false you need to provide the following variables: @@ -115,10 +116,11 @@ nexus_config_bower: false nexus_config_npm: false nexus_config_nuget: false nexus_config_gitlfs: false +nexus_config_yum: false # also see _nexus_privilege_defaults below nexus_privileges: - - name: all-repos-read # used as key to update a privilege + - name: all-repos-read # used as key to update a privilege description: 'Read & Browse access to all repos' repository: '*' actions: @@ -126,7 +128,7 @@ nexus_privileges: - browse nexus_roles: - - id: Developpers # can map to a LDAP group id, also used as a key to update a role + - id: Developpers # can map to a LDAP group id, also used as a key to update a role name: developers description: All developers privileges: @@ -170,6 +172,8 @@ nexus_blob_names: # Splited blob name list @ blob_vars.yml blob: 'default' gitlfs: blob: 'default' + yum: + blob: 'default' nexus_blobstores: [] @@ -202,23 +206,52 @@ nexus_repos_maven_group: - central - jboss - -nexus_scheduled_tasks: - - name: db-backup # Note: CRON must be aligned to nexus-blob-backup.sh cron schedule. -> Task: "Config nexus-backup shell cron" - cron: '0 0 21 * * ?' - typeId: db.backup - task_alert_email: alerts@example.org # optional - taskProperties: - location: "{{ nexus_backup_dir }}/" - - -# example task to compact blobstore : -# - name: compact-blobstore +######## +# Nexus Backup +# Shall we configure backup ? +nexus_backup_configure: false +# Backup time cron expression +# Current limitation: can only be ran once a day +nexus_backup_cron: "* 0 21 * * ?" # See cron expression in nexus create task GUI + +# Scheduled tasks +# Note: these are tasks you define by yourself (default: none) +# If you used `nexus_backup_configure: true` above you will see a scheduled task for this +# in your GUI which is not part of the below list +nexus_scheduled_tasks: [] +# # Example task to compact blobstore : +# - name: compact-docker-blobstore # cron: '0 0 22 * * ?' # typeId: blobstore.compact -# task_alert_email: alerts@example.org # optional +# task_alert_email: alerts@example.org # optional +# taskProperties: +# blobstoreName: {{ nexus_blob_names.docker.blob }} # all task attributes are stored as strings by nexus internally +# # Example task to purge maven snapshots +# - name: Purge-maven-snapshots +# cron: '0 50 23 * * ?' +# typeId: repository.maven.remove-snapshots +# task_alert_email: alerts@example.org # optional # taskProperties: -# blobstoreName: 'default' # all task attributes are stored as strings by nexus internally +# repositoryName: "*" # * for all repos. Change to a repository name if you only want a specific one +# minimumRetained: "2" +# snapshotRetentionDays: "2" +# gracePeriodInDays: "2" +# booleanTaskProperties: +# removeIfReleased: true +# # Example task to purge unused docker manifest and images +# - name: Purge unused docker manifests and images +# cron: '0 55 23 * * ?' +# typeId: "repository.docker.gc" +# task_alert_email: alerts@example.org # optional +# taskProperties: +# repositoryName: "*" # * for all repos. Change to a repository name if you only want a specific one +# # Example task to purge incomplete docker uploads +# - name: Purge incomplete docker uploads +# cron: '0 0 0 * * ?' +# typeId: "repository.docker.upload-purge" +# task_alert_email: alerts@example.org # optional +# taskProperties: +# age: "24" _nexus_privilege_defaults: type: repository-view @@ -229,17 +262,17 @@ _nexus_privilege_defaults: _nexus_repos_maven_defaults: blob_store: "{{ nexus_blob_names.mvn.blob }}" strict_content_validation: true - version_policy: release # release, snapshot or mixed - layout_policy: strict # strict or permissive - write_policy: allow_once # allow_once or allow + version_policy: release # release, snapshot or mixed + layout_policy: strict # strict or permissive + write_policy: allow_once # allow_once or allow # pypi support ... _nexus_repos_pypi_defaults: blob_store: "{{ nexus_blob_names.pypi.blob }}" strict_content_validation: true - version_policy: release # release, snapshot or mixed - layout_policy: strict # strict or permissive - write_policy: allow_once # allow_once or allow + version_policy: release # release, snapshot or mixed + layout_policy: strict # strict or permissive + write_policy: allow_once # allow_once or allow nexus_repos_pypi_hosted: - name: pypi-internal @@ -261,9 +294,9 @@ nexus_repos_pypi_proxy: _nexus_repos_raw_defaults: blob_store: "{{ nexus_blob_names.raw.blob }}" strict_content_validation: true - version_policy: release # release, snapshot or mixed - layout_policy: strict # strict or permissive - write_policy: allow_once # allow_once or allow + version_policy: release # release, snapshot or mixed + layout_policy: strict # strict or permissive + write_policy: allow_once # allow_once or allow nexus_repos_raw_proxy: - name: ubuntu-archive @@ -285,9 +318,9 @@ _nexus_repos_docker_defaults: blob_store: "{{ nexus_blob_names.docker.blob }}" force_basic_auth: true strict_content_validation: true - version_policy: release # release, snapshot or mixed - layout_policy: strict # strict or permissive - write_policy: allow_once # allow_once or allow + version_policy: release # release, snapshot or mixed + layout_policy: strict # strict or permissive + write_policy: allow_once # allow_once or allow nexus_repos_docker_hosted: - name: docker-hosted @@ -314,7 +347,7 @@ nexus_repos_docker_group: _nexus_repos_rubygems_defaults: blob_store: "{{ nexus_blob_names.ruby.blob }}" strict_content_validation: true - write_policy: allow_once # allow_once or allow + write_policy: allow_once # allow_once or allow nexus_repos_rubygems_hosted: - name: rubygems-hosted @@ -336,7 +369,7 @@ nexus_repos_rubygems_proxy: _nexus_repos_bower_defaults: blob_store: "{{ nexus_blob_names.bower.blob }}" strict_content_validation: true - write_policy: allow_once # allow_once or allow + write_policy: allow_once # allow_once or allow nexus_repos_bower_hosted: - name: bower-internal @@ -358,7 +391,7 @@ nexus_repos_bower_proxy: _nexus_repos_npm_defaults: blob_store: "{{ nexus_blob_names.npm.blob }}" strict_content_validation: true - write_policy: allow_once # allow_once or allow + write_policy: allow_once # allow_once or allow nexus_repos_npm_hosted: - name: npm-internal @@ -379,7 +412,7 @@ nexus_repos_npm_proxy: _nexus_repos_nuget_defaults: blob_store: "{{ nexus_blob_names.nuget.blob }}" strict_content_validation: true - write_policy: allow_once # allow_once or allow + write_policy: allow_once # allow_once or allow nexus_repos_nuget_hosted: - name: nuget-internal @@ -406,3 +439,13 @@ _nexus_repos_gitlfs_defaults: nexus_repos_gitlfs_hosted: - name: gitlfs-internal blob_store: "{{ nexus_blob_names.gitlfs.blob }}" + +# yum support ... +nexus_repos_yum_proxy: [] +# Example for epel centos-7 x86_64 +# - name: epel_centos_7_x86_64 +# remote_url: http://download.fedoraproject.org/pub/epel/7/x86_64 + +_nexus_repos_yum_defaults: + blob_store: "{{ nexus_blob_names.yum.blob }}" + strict_content_validation: true diff --git a/files/groovy/create_repo_nuget_hosted.groovy b/files/groovy/create_repo_nuget_hosted.groovy index eee99d81..e22cb8d8 100644 --- a/files/groovy/create_repo_nuget_hosted.groovy +++ b/files/groovy/create_repo_nuget_hosted.groovy @@ -11,7 +11,6 @@ if (existingRepository != null) { newConfig = existingRepository.configuration.copy() // We only update values we are allowed to change (cf. greyed out options in gui) - newConfig.attributes['group']['memberNames'] = parsed_args.member_repos newConfig.attributes['storage']['writePolicy'] = parsed_args.write_policy.toUpperCase() newConfig.attributes['storage']['strictContentTypeValidation'] = Boolean.valueOf(parsed_args.strict_content_validation) diff --git a/files/groovy/create_repo_yum_proxy.groovy b/files/groovy/create_repo_yum_proxy.groovy new file mode 100644 index 00000000..3a5bf1d1 --- /dev/null +++ b/files/groovy/create_repo_yum_proxy.groovy @@ -0,0 +1,59 @@ +import groovy.json.JsonSlurper +import org.sonatype.nexus.repository.config.Configuration + +parsed_args = new JsonSlurper().parseText(args) + +repositoryManager = repository.repositoryManager + +authentication = parsed_args.remote_username == null ? null : [ + type: 'username', + username: parsed_args.remote_username, + password: parsed_args.remote_password +] + +existingRepository = repositoryManager.get(parsed_args.name) + +if (existingRepository != null) { + + newConfig = existingRepository.configuration.copy() + // We only update values we are allowed to change (cf. greyed out options in gui) + newConfig.attributes['proxy']['remoteUrl'] = parsed_args.remote_url + newConfig.attributes['httpclient']['authentication'] = authentication + newConfig.attributes['storage']['strictContentTypeValidation'] = Boolean.valueOf(parsed_args.strict_content_validation) + + repositoryManager.update(newConfig) + +} else { + + configuration = new Configuration( + repositoryName: parsed_args.name, + recipeName: 'yum-proxy', + online: true, + attributes: [ + proxy : [ + remoteUrl: parsed_args.remote_url, + contentMaxAge: 1440.0, + metadataMaxAge: 1440.0 + ], + httpclient: [ + blocked: false, + autoBlock: true, + authentication: authentication, + connection: [ + useTrustStore: false + ] + ], + storage: [ + blobStoreName: parsed_args.blob_store, + strictContentTypeValidation: Boolean.valueOf(parsed_args.strict_content_validation) + ], + negativeCache: [ + enabled: true, + timeToLive: 1440.0 + ] + ] + ) + + repositoryManager.create(configuration) + +} diff --git a/files/groovy/create_task.groovy b/files/groovy/create_task.groovy index 0f1f6bf0..9eb574ed 100644 --- a/files/groovy/create_task.groovy +++ b/files/groovy/create_task.groovy @@ -25,6 +25,8 @@ if (parsed_args.task_alert_email) { taskConfiguration.setAlertEmail(parsed_args.task_alert_email) } +parsed_args.booleanTaskProperties.each { key, value -> taskConfiguration.setBoolean(key, Boolean.valueOf(value)) } + Schedule schedule = taskScheduler.scheduleFactory.cron(new Date(), parsed_args.cron) taskScheduler.scheduleTask(taskConfiguration, schedule) diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 00000000..756fd7ba --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,42 @@ +--- +- name: systemd-reload + systemd: + daemon-reload: yes + name: nexus.service + no_block: yes + +- name: nexus-service-restart + systemd: + name: nexus.service + state: restarted + no_block: yes + +- name: nexus-service-stop + systemd: + name: nexus.service + state: stopped + no_block: yes + when: nexus_systemd_service_file.stat.exists + +- name: wait-for-nexus + wait_for: + path: "{{ nexus_data_dir }}/log/nexus.log" + search_regex: "Started Sonatype Nexus OSS .*" + timeout: 1800 + +- name: wait-for-nexus-port + wait_for: + port: "{{ nexus_default_port }}" + delay: 5 + +- name: httpd-service-reload + systemd: + name: "{{ httpd_package_name }}.service" + state: reloaded + enabled: yes + no_block: yes + +- name: wait-for-httpd + wait_for: + port: 443 + delay: 5 diff --git a/meta/main.yml b/meta/main.yml index 1efad77e..cea8e33d 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,3 +1,4 @@ +--- galaxy_info: author: ansible-ThoTeam description: Nexus Repository Manager 3.x @@ -5,17 +6,17 @@ galaxy_info: license: license (GPLv3) - min_ansible_version: 2.1 + min_ansible_version: 2.2 github_branch: master platforms: - name: EL versions: - - 7 + - 7 - name: Ubuntu versions: - - all + - all galaxy_tags: - nexus diff --git a/molecule/default/Dockerfile.j2 b/molecule/default/Dockerfile.j2 deleted file mode 100644 index 74b47aec..00000000 --- a/molecule/default/Dockerfile.j2 +++ /dev/null @@ -1,7 +0,0 @@ -FROM {{ item.image }} - -RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates cron && apt-get clean; \ - elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python python-devel python2-dnf bash cron && dnf clean all; \ - elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash crontabs && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ - elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml cron && zypper clean -a; \ - elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates cron; fi diff --git a/molecule/default/INSTALL.rst b/molecule/default/INSTALL.rst index 09e87359..bba8928b 100644 --- a/molecule/default/INSTALL.rst +++ b/molecule/default/INSTALL.rst @@ -8,7 +8,7 @@ being used. Requirements ============ -* Ansible 2.2 +* Ansible 2.3 * Docker Engine * docker-py diff --git a/molecule/default/create.yml b/molecule/default/create.yml index ac0110be..3b1071c2 100644 --- a/molecule/default/create.yml +++ b/molecule/default/create.yml @@ -4,44 +4,47 @@ connection: local gather_facts: False no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" + vars: molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" - molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}" - molecule_scenario_directory: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}" molecule_yml: "{{ lookup('file', molecule_file) | from_yaml }}" - tasks: - - name: Create Dockerfiles from image names - template: - src: "{{ molecule_scenario_directory }}/Dockerfile.j2" - dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}" - with_items: "{{ molecule_yml.platforms }}" - register: platforms + molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}" - - name: Discover local Docker images - docker_image_facts: - name: "molecule_local/{{ item.item.name }}" - with_items: "{{ platforms.results }}" - register: docker_images + tasks: - - name: Build an Ansible compatible image - docker_image: - path: "{{ molecule_ephemeral_directory }}" - name: "molecule_local/{{ item.item.image }}" - dockerfile: "{{ item.item.dockerfile | default(item.invocation.module_args.dest) }}" - force: "{{ item.item.force | default(True) }}" - with_items: "{{ platforms.results }}" - when: platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0 + - name: include variables from tested playbook + include_vars: + file: "{{ molecule_ephemeral_directory }}/../../../defaults/main.yml" - name: Create molecule instance(s) docker_container: name: "{{ item.name }}" hostname: "{{ item.name }}" - image: "molecule_local/{{ item.image }}" + image: "{{ item.image }}" state: started recreate: False + pull: true log_driver: syslog command: "{{ item.command | default('sleep infinity') }}" privileged: "{{ item.privileged | default(omit) }}" volumes: "{{ item.volumes | default(omit) }}" capabilities: "{{ item.capabilities | default(omit) }}" + ports: "{{ item.ports | default(omit) }}" + with_items: "{{ molecule_yml.platforms }}" + + - name: create a dir in {{ molecule_ephemeral_directory }} for nexus package download + file: + path: "{{ molecule_ephemeral_directory }}/nexus-downloads" + state: directory + + - name: get the current nexus version + get_url: + url: "http://download.sonatype.com/nexus/3/{{ nexus_package }}" + dest: "{{ molecule_ephemeral_directory }}/nexus-downloads/{{ nexus_package }}" + force: no + + - name: copy nexus package do default image location into images + shell: "docker cp \ + {{ molecule_ephemeral_directory }}/nexus-downloads/{{ nexus_package }} \ + {{ item.name }}:/tmp/{{ nexus_package }}" with_items: "{{ molecule_yml.platforms }}" diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index b1840e1d..4868baff 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,44 +1,40 @@ --- dependency: name: galaxy + driver: name: docker + safe_files: + - nexus-downloads + lint: name: yamllint + platforms: - name: ubuntu-16.04 - image: ubuntu - image_version: '16.04' + image: thoteam/ansible-ubuntu16.04-apache-java + image_version: latest command: /lib/systemd/systemd privileged: true + ports: + - 8090:443 - name: centos-7 - image: centos - image_version: '7' - command: /lib/systemd/systemd + image: thoteam/ansible-centos7-apache-java + image_version: latest + command: /usr/sbin/init privileged: true - # - name: centos-8 - # image: centos - # image_version: '8' - # command: /lib/systemd/systemd - # privileged: true - # - name: opensuse-13.2 - # image: opensuse - # image_version: '13.2' - # command: /lib/systemd/systemd - # privileged: true - # - name: opensuse-42.3 - # image: opensuse - # image_version: '42.3' - # command: /lib/systemd/systemd - # privileged: true + ports: + - 8091:443 + provisioner: name: ansible lint: name: ansible-lint - enabled: False scenario: name: default + create_sequence: + - create check_sequence: - destroy - create @@ -48,16 +44,17 @@ scenario: converge_sequence: - create - converge - destroy_sequence: - - destroy test_sequence: + - lint - destroy - - dependency + - syntax - create - converge - - lint + - idempotence + - check - verify - destroy + verifier: name: testinfra lint: diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml index 2f337089..5f68cdc5 100644 --- a/molecule/default/playbook.yml +++ b/molecule/default/playbook.yml @@ -1,6 +1,49 @@ --- - name: Converge hosts: all + pre_tasks: + - name: configure default ssl key and cert based on OS + include_vars: "../ssl-{{ ansible_os_family }}.yml" roles: - - role: ansiblebit.oracle-java - role: nexus3-oss + vars: + httpd_setup_enable: true + httpd_copy_ssl_files: false + httpd_ssl_cert_file_location: "{{ default_cert }}" + httpd_ssl_cert_key_location: "{{ default_key }}" + public_hostname: localhost + + nexus_backup_configure: true + + nexus_delete_default_repos: true + nexus_delete_default_blobstore: true + + nexus_blob_split: false + + nexus_config_pypi: true + nexus_config_docker: true + nexus_config_raw: true + nexus_config_rubygems: true + nexus_config_bower: true + nexus_config_npm: true + nexus_config_nuget: true + nexus_config_gitlfs: true + nexus_config_yum: true + + nexus_repos_yum_proxy: + - name: epel_centos_7_x86_64 + remote_url: http://download.fedoraproject.org/pub/epel/7/x86_64 + + nexus_scheduled_tasks: + # Example task to purge maven snapshots + - name: Purge-maven-snapshots + cron: '0 50 23 * * ?' + typeId: repository.maven.remove-snapshots + task_alert_email: alerts@example.org # optional + taskProperties: + repositoryName: "*" + minimumRetained: "2" + snapshotRetentionDays: "2" + gracePeriodInDays: "2" + booleanTaskProperties: + removeIfReleased: true diff --git a/molecule/default/requirements.yml b/molecule/default/requirements.yml deleted file mode 100644 index 2558a535..00000000 --- a/molecule/default/requirements.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- - -- src: ansiblebit.oracle-java diff --git a/molecule/selinux/INSTALL.rst b/molecule/selinux/INSTALL.rst new file mode 100644 index 00000000..44c26afd --- /dev/null +++ b/molecule/selinux/INSTALL.rst @@ -0,0 +1,17 @@ +******* +Install +******* + +Requirements +============ + +* Vagrant +* Virtualbox, Parallels, VMware Fusion, VMware Workstation or VMware Desktop +* python-vagrant + +Install +======= + +.. code-block:: bash + + $ sudo pip install python-vagrant diff --git a/molecule/selinux/create.yml b/molecule/selinux/create.yml new file mode 100644 index 00000000..f5a60217 --- /dev/null +++ b/molecule/selinux/create.yml @@ -0,0 +1,60 @@ +--- +- name: Create + hosts: localhost + connection: local + gather_facts: false + no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" + vars: + molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" + molecule_instance_config: "{{ lookup('env', 'MOLECULE_INSTANCE_CONFIG') }}" + molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" + tasks: + - name: Create molecule instance(s) + molecule_vagrant: + instance_name: "{{ item.name }}" + instance_interfaces: "{{ item.interfaces | default(omit) }}" + instance_raw_config_args: "{{ item.instance_raw_config_args | default(omit) }}" + + platform_box: "{{ item.box }}" + platform_box_version: "{{ item.box_version | default(omit) }}" + platform_box_url: "{{ item.box_url | default(omit) }}" + + provider_name: "{{ molecule_yml.driver.provider.name }}" + provider_memory: "{{ item.memory | default(omit) }}" + provider_cpus: "{{ item.cpus | default(omit) }}" + provider_raw_config_args: "{{ item.raw_config_args | default(omit) }}" + + state: up + register: server + with_items: "{{ molecule_yml.platforms }}" + + # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance creation + # causes issues. + + # Mandatory configuration for Molecule to function. + + - name: Populate instance config dict + set_fact: + instance_conf_dict: { + 'instance': "{{ item.Host }}", + 'address': "{{ item.HostName }}", + 'user': "{{ item.User }}", + 'port': "{{ item.Port }}", + 'identity_file': "{{ item.IdentityFile }}", + } + with_items: "{{ server.results }}" + register: instance_config_dict + when: server.changed | bool + + - name: Convert instance config dict to a list + set_fact: + instance_conf: "{{ instance_config_dict.results | map(attribute='ansible_facts.instance_conf_dict') | list }}" + when: server.changed | bool + + - name: Dump instance config + copy: + # NOTE(retr0h): Workaround for Ansible 2.2. + # https://github.com/ansible/ansible/issues/20885 + content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" + dest: "{{ molecule_instance_config }}" + when: server.changed | bool diff --git a/molecule/selinux/destroy.yml b/molecule/selinux/destroy.yml new file mode 100644 index 00000000..2f55d552 --- /dev/null +++ b/molecule/selinux/destroy.yml @@ -0,0 +1,39 @@ +--- + +- name: Destroy + hosts: localhost + connection: local + gather_facts: false + no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" + vars: + molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}" + molecule_instance_config: "{{ lookup('env',' MOLECULE_INSTANCE_CONFIG') }}" + molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}" + tasks: + - name: Destroy molecule instance(s) + molecule_vagrant: + instance_name: "{{ item.name }}" + platform_box: "{{ item.box }}" + provider_name: "{{ molecule_yml.driver.provider.name }}" + force_stop: "{{ item.force_stop | default(true) }}" + + state: destroy + register: server + with_items: "{{ molecule_yml.platforms }}" + + # NOTE(retr0h): Vagrant/VBox sucks and parallelizing instance deletion + # causes issues. + + # Mandatory configuration for Molecule to function. + + - name: Populate instance config + set_fact: + instance_conf: {} + + - name: Dump instance config + copy: + # NOTE(retr0h): Workaround for Ansible 2.2. + # https://github.com/ansible/ansible/issues/20885 + content: "{{ instance_conf | to_json | from_json | molecule_to_yaml | molecule_header }}" + dest: "{{ molecule_instance_config }}" + when: server.changed | bool diff --git a/molecule/selinux/molecule.yml b/molecule/selinux/molecule.yml new file mode 100644 index 00000000..51eda340 --- /dev/null +++ b/molecule/selinux/molecule.yml @@ -0,0 +1,30 @@ +--- +dependency: + name: galaxy +driver: + name: vagrant + provider: + name: virtualbox +lint: + name: yamllint +platforms: + - name: vb-centos7 + box: thoteam/vb-centos7 + box_url: http://vagrant.thoteam.com/vb-centos7/vb-centos7.json + cpu: 4 + memory: 4096 + - name: vb-debian-stretch + box: thoteam/vb-stretch + box_url: http://vagrant.thoteam.com/vb-stretch/vb-stretch.json + cpu: 4 + memory: 4096 +provisioner: + name: ansible + lint: + name: ansible-lint +scenario: + name: selinux +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/selinux/playbook.yml b/molecule/selinux/playbook.yml new file mode 100644 index 00000000..5bf5c521 --- /dev/null +++ b/molecule/selinux/playbook.yml @@ -0,0 +1,14 @@ +--- +- name: Converge + hosts: all + become: yes + pre_tasks: + - name: configure default ssl key and cert based on OS + include_vars: "../ssl-{{ ansible_os_family }}.yml" + roles: + - role: nexus3-oss + vars: + httpd_setup_enable: true + httpd_copy_ssl_files: false + httpd_ssl_cert_file_location: "{{ default_cert }}" + httpd_ssl_cert_key_location: "{{ default_key }}" diff --git a/molecule/selinux/prepare.yml b/molecule/selinux/prepare.yml new file mode 100644 index 00000000..6befd47b --- /dev/null +++ b/molecule/selinux/prepare.yml @@ -0,0 +1,31 @@ +--- +- name: Prepare + hosts: all + become: true + tasks: + - name: Install needed dependencies for role testing (redhat) + yum: + name: "{{ item }}" + state: present + with_items: + - java-1.8.0-openjdk-headless + - httpd + - mod_ssl + - rsync + when: ansible_os_family == 'RedHat' + + - block: + - name: Install needed dependencie for role testing (debian/ubuntu) + apt: + name: "{{ item }}" + state: present + update_cache: true + with_items: + - apache2 + - openjdk-8-jre-headless + - rsync + + - name: Enable needed apache modules + shell: a2enmod ssl rewrite proxy proxy_http headers + + when: ansible_os_family == 'Debian' diff --git a/molecule/selinux/tests/test_default.py b/molecule/selinux/tests/test_default.py new file mode 100644 index 00000000..eedd64a1 --- /dev/null +++ b/molecule/selinux/tests/test_default.py @@ -0,0 +1,14 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_hosts_file(host): + f = host.file('/etc/hosts') + + assert f.exists + assert f.user == 'root' + assert f.group == 'root' diff --git a/molecule/ssl-Debian.yml b/molecule/ssl-Debian.yml new file mode 100644 index 00000000..74304afb --- /dev/null +++ b/molecule/ssl-Debian.yml @@ -0,0 +1,3 @@ +--- +default_cert: /etc/ssl/certs/ssl-cert-snakeoil.pem +default_key: /etc/ssl/private/ssl-cert-snakeoil.key diff --git a/molecule/ssl-RedHat.yml b/molecule/ssl-RedHat.yml new file mode 100644 index 00000000..44835cbd --- /dev/null +++ b/molecule/ssl-RedHat.yml @@ -0,0 +1,3 @@ +--- +default_cert: /etc/pki/tls/certs/localhost.crt +default_key: /etc/pki/tls/private/localhost.key diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..de364b0c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,23 @@ +################################## +## Python requirement for testing. +## For testing locally, you can import in a virtualenv +## i.e. +## virtualenv --python=python3 /path/topyenv-nexus3-oss +## . /path/to/pyenv-nexus3-oss/bin/activate +## pip install -r pyrequirements.txt +## ./tests/run_all_tests.sh +## deactivate +## +## Note: the virtualenv should be created outside of the +## project index or it will interfere with linting the role +## and produce unwanted errors. +################################## + +# Latest ansible 2.3.x +ansible>=2.3,<2.4 +# Latest molecule +molecule +# Latest docker-py +docker-py +# Python vagrant only needed for local test for selinux +# python-vagrant diff --git a/tasks/configure-Debian.yml b/tasks/configure-Debian.yml index 9344dbf0..d81f6130 100644 --- a/tasks/configure-Debian.yml +++ b/tasks/configure-Debian.yml @@ -2,6 +2,5 @@ httpd_package_name: "apache2" httpd_config_dir: "/etc/{{ httpd_package_name }}/sites-enabled" -selinux_enabled: false certificate_file_dest: "/etc/ssl/certs" -certificate_key_dest: "/etc/ssl/private" \ No newline at end of file +certificate_key_dest: "/etc/ssl/private" diff --git a/tasks/configure-RedHat.yml b/tasks/configure-RedHat.yml index 8140c80a..0d247100 100644 --- a/tasks/configure-RedHat.yml +++ b/tasks/configure-RedHat.yml @@ -2,6 +2,5 @@ httpd_package_name: "httpd" httpd_config_dir: "/etc/{{ httpd_package_name }}/conf.d" -selinux_enabled: true certificate_file_dest: "/etc/pki/tls/certs" -certificate_key_dest: "/etc/pki/tls/private" \ No newline at end of file +certificate_key_dest: "/etc/pki/tls/private" diff --git a/tasks/create_repo_yum_proxy_each.yml b/tasks/create_repo_yum_proxy_each.yml new file mode 100644 index 00000000..c0ae0d03 --- /dev/null +++ b/tasks/create_repo_yum_proxy_each.yml @@ -0,0 +1,5 @@ +--- +- include: call_script.yml + vars: + script_name: create_repo_yum_proxy + args: "{{ _nexus_repos_yum_defaults|combine(item) }}" diff --git a/tasks/declare_script_each.yml b/tasks/declare_script_each.yml index ad46e4f3..5bd23f26 100644 --- a/tasks/declare_script_each.yml +++ b/tasks/declare_script_each.yml @@ -21,4 +21,3 @@ name: "{{ item }}" type: 'groovy' content: "{{ lookup('file', 'groovy/' + item + '.groovy') }}" - diff --git a/tasks/httpd_reverse_proxy_config.yml b/tasks/httpd_reverse_proxy_config.yml index 106f4119..c8e60906 100644 --- a/tasks/httpd_reverse_proxy_config.yml +++ b/tasks/httpd_reverse_proxy_config.yml @@ -1,37 +1,38 @@ --- -- name: Include OS specific variables. - include_vars: "configure-{{ ansible_os_family }}.yml" - - name: Copy {{ httpd_package_name }} vhost template: src: "nexus-vhost.conf" dest: "{{ httpd_config_dir }}" + notify: + - httpd-service-reload + - wait-for-httpd - name: Copy SSL certificate file copy: src: "{{ httpd_ssl_certificate_file }}" dest: "{{ certificate_file_dest }}" - mode: 600 + mode: 0600 when: httpd_copy_ssl_files + notify: + - httpd-service-reload + - wait-for-httpd - name: Copy SSL certificate key file copy: src: "{{ httpd_ssl_certificate_key_file }}" dest: "{{ certificate_key_dest }}" - mode: 600 + mode: 0600 when: httpd_copy_ssl_files + notify: + - httpd-service-reload + - wait-for-httpd - name: Setsebool httpd_can_network_connect - shell: 'setsebool -P httpd_can_network_connect on' - when: selinux_enabled - -- name: Restart {{ httpd_package_name }} - systemd: - state: restarted - name: "{{ httpd_package_name }}" + seboolean: + name: httpd_can_network_connect + persistent: yes + state: yes + when: ansible_selinux.status is defined and ansible_selinux.status == "enabled" -- name: Waiting for {{ httpd_package_name }} to be restarted - wait_for: - port: 443 - delay: 5 \ No newline at end of file +- meta: flush_handlers diff --git a/tasks/main.yml b/tasks/main.yml index 178ff153..21cf630d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,4 +1,17 @@ --- + +- name: Include OS specific variables. + include_vars: "configure-{{ ansible_os_family }}.yml" + +- name: Include OS specific selinux libs and utils if needed + include: "selinux-{{ ansible_os_family }}.yml" + when: ansible_selinux.status is defined and ansible_selinux.status == "enabled" + +- name: Check if SystemD service is installed + stat: + path: /etc/systemd/system/nexus.service + register: nexus_systemd_service_file + - include: nexus_purge.yml when: ((purge is defined) and (purge | bool)) @@ -34,6 +47,7 @@ - name: "{{ nexus_blob_names.nuget.blob }}" - name: "{{ nexus_blob_names.mvn.blob }}" - name: "{{ nexus_blob_names.gitlfs.blob }}" + - name: "{{ nexus_blob_names.yum.blob }}" when: nexus_data_dir_contents.stdout == "" and nexus_delete_default_blobstore - include: setup_ldap_each.yml @@ -70,78 +84,78 @@ with_items: "{{ nexus_repos_maven_group }}" - block: - - include: create_repo_docker_hosted_each.yml - with_items: "{{ nexus_repos_docker_hosted }}" + - include: create_repo_docker_hosted_each.yml + with_items: "{{ nexus_repos_docker_hosted }}" - - include: create_repo_docker_proxy_each.yml - with_items: "{{ nexus_repos_docker_proxy }}" + - include: create_repo_docker_proxy_each.yml + with_items: "{{ nexus_repos_docker_proxy }}" - - include: create_repo_docker_group_each.yml - with_items: "{{ nexus_repos_docker_group }}" + - include: create_repo_docker_group_each.yml + with_items: "{{ nexus_repos_docker_group }}" when: nexus_config_docker - block: - - include: create_repo_pypi_proxy_each.yml - with_items: "{{ nexus_repos_pypi_proxy }}" + - include: create_repo_pypi_proxy_each.yml + with_items: "{{ nexus_repos_pypi_proxy }}" - - include: create_repo_pypi_hosted_each.yml - with_items: "{{ nexus_repos_pypi_hosted }}" + - include: create_repo_pypi_hosted_each.yml + with_items: "{{ nexus_repos_pypi_hosted }}" - - include: create_repo_pypi_group_each.yml - with_items: "{{ nexus_repos_pypi_group }}" + - include: create_repo_pypi_group_each.yml + with_items: "{{ nexus_repos_pypi_group }}" when: nexus_config_pypi - block: - - include: create_repo_raw_proxy_each.yml - with_items: "{{ nexus_repos_raw_proxy }}" + - include: create_repo_raw_proxy_each.yml + with_items: "{{ nexus_repos_raw_proxy }}" - - include: create_repo_raw_hosted_each.yml - with_items: "{{ nexus_repos_raw_hosted }}" + - include: create_repo_raw_hosted_each.yml + with_items: "{{ nexus_repos_raw_hosted }}" - - include: create_repo_raw_group_each.yml - with_items: "{{ nexus_repos_raw_group }}" + - include: create_repo_raw_group_each.yml + with_items: "{{ nexus_repos_raw_group }}" when: nexus_config_raw - block: - - include: create_repo_rubygems_proxy_each.yml - with_items: "{{ nexus_repos_rubygems_proxy }}" + - include: create_repo_rubygems_proxy_each.yml + with_items: "{{ nexus_repos_rubygems_proxy }}" - - include: create_repo_rubygems_hosted_each.yml - with_items: "{{ nexus_repos_rubygems_hosted }}" + - include: create_repo_rubygems_hosted_each.yml + with_items: "{{ nexus_repos_rubygems_hosted }}" - - include: create_repo_rubygems_group_each.yml - with_items: "{{ nexus_repos_rubygems_group }}" + - include: create_repo_rubygems_group_each.yml + with_items: "{{ nexus_repos_rubygems_group }}" when: nexus_config_rubygems - block: - - include: create_repo_bower_proxy_each.yml - with_items: "{{ nexus_repos_bower_proxy }}" + - include: create_repo_bower_proxy_each.yml + with_items: "{{ nexus_repos_bower_proxy }}" - - include: create_repo_bower_hosted_each.yml - with_items: "{{ nexus_repos_bower_hosted }}" + - include: create_repo_bower_hosted_each.yml + with_items: "{{ nexus_repos_bower_hosted }}" - - include: create_repo_bower_group_each.yml - with_items: "{{ nexus_repos_bower_group }}" + - include: create_repo_bower_group_each.yml + with_items: "{{ nexus_repos_bower_group }}" when: nexus_config_bower - block: - - include: create_repo_npm_proxy_each.yml - with_items: "{{ nexus_repos_npm_proxy }}" + - include: create_repo_npm_proxy_each.yml + with_items: "{{ nexus_repos_npm_proxy }}" - - include: create_repo_npm_hosted_each.yml - with_items: "{{ nexus_repos_npm_hosted }}" + - include: create_repo_npm_hosted_each.yml + with_items: "{{ nexus_repos_npm_hosted }}" - - include: create_repo_npm_group_each.yml - with_items: "{{ nexus_repos_npm_group }}" + - include: create_repo_npm_group_each.yml + with_items: "{{ nexus_repos_npm_group }}" when: nexus_config_npm - block: - - include: create_repo_nuget_proxy_each.yml - with_items: "{{ nexus_repos_nuget_proxy }}" - - include: create_repo_nuget_hosted_each.yml - with_items: "{{ nexus_repos_nuget_hosted }}" - - include: create_repo_nuget_group_each.yml - with_items: "{{ nexus_repos_nuget_group }}" + - include: create_repo_nuget_proxy_each.yml + with_items: "{{ nexus_repos_nuget_proxy }}" + - include: create_repo_nuget_hosted_each.yml + with_items: "{{ nexus_repos_nuget_hosted }}" + - include: create_repo_nuget_group_each.yml + with_items: "{{ nexus_repos_nuget_group }}" when: nexus_config_nuget @@ -149,6 +163,10 @@ with_items: "{{ nexus_repos_gitlfs_hosted }}" when: nexus_config_gitlfs +- include: create_repo_yum_proxy_each.yml + with_items: "{{ nexus_repos_yum_proxy }}" + when: nexus_config_yum + - include: call_script.yml vars: script_name: setup_anonymous_access @@ -218,3 +236,16 @@ - include: create_task_each.yml with_items: "{{ nexus_scheduled_tasks }}" + +- name: Configure nexus backup task + include: call_script.yml + vars: + script_name: create_task + args: + name: db and blobstores backup + typeId: script + cron: "{{ nexus_backup_cron }}" + taskProperties: + language: groovy + source: "{{ lookup('template', './templates/backup.groovy.j2') }}" + when: nexus_backup_configure | bool diff --git a/tasks/nexus-restore.yml b/tasks/nexus-restore.yml index 1db8d996..0f8e384c 100644 --- a/tasks/nexus-restore.yml +++ b/tasks/nexus-restore.yml @@ -1,17 +1,14 @@ --- - name: "Run restoration script" shell: "nexus-blob-restore.sh {{ nexus_restore_point }} 2>&1 | tee -a {{ nexus_restore_log }}" + tags: + # This is only run when a restore point is defined + # shut-off ansible-lint error on this one: this is the desired way of doing it + - skip_ansible_lint -- name: Restart systemd service - shell: 'systemctl restart nexus.service' + notify: + - nexus-service-restart + - wait-for-nexus + - wait-for-nexus-port -- name: Waiting for Nexus service to be ready... - wait_for: - path: "{{ nexus_data_dir }}/log/nexus.log" - search_regex: "Started Sonatype Nexus OSS .*" - timeout: 1800 - -- name: Waiting for nexus to be ready... - wait_for: - port: "{{ nexus_default_port }}" - delay: 5 \ No newline at end of file +- meta: flush_handlers diff --git a/tasks/nexus_install.yml b/tasks/nexus_install.yml index 16b4ff2b..85511d47 100644 --- a/tasks/nexus_install.yml +++ b/tasks/nexus_install.yml @@ -4,6 +4,8 @@ url: "http://download.sonatype.com/nexus/3/{{ nexus_package }}" dest: "{{ nexus_download_dir }}/{{ nexus_package }}" force: no + notify: + - nexus-service-stop - name: Ensure Nexus o/s group exists group: @@ -29,15 +31,10 @@ creates: "{{ nexus_installation_dir }}/nexus-{{ nexus_version }}" force: no copy: false + notify: + - nexus-service-stop -- name: Check if SystemD service is installed - stat: - path: /etc/systemd/system/nexus.service - register: nexus_systemd_service_file - -- name: Stop systemd service - shell: 'systemctl stop nexus.service' - when: nexus_systemd_service_file.stat.exists +- meta: flush_handlers - name: Update symlink nexus-latest file: @@ -89,6 +86,11 @@ mode: "0755" recurse: false with_items: "{{ nexus_app_dir_settings_dirs }}" + when: nexus_latest_version.changed + register: chown_config_first_time + tags: + # hard to run as a handler for time being + - skip_ansible_lint - name: Create Nexus data directory file: @@ -122,8 +124,8 @@ owner: "{{ nexus_os_user }}" group: "{{ nexus_os_group }}" with_items: - - "{{ nexus_tmp_dir }}" - - "{{ nexus_backup_dir }}" + - "{{ nexus_tmp_dir }}" + - "{{ nexus_backup_dir }}" - name: Setup Nexus tmp directory lineinfile: @@ -166,60 +168,49 @@ template: src: "nexus.service" dest: "/etc/systemd/system" - -# systemd available from ansible 2.2 only -# - name: Enable nexus service -# systemd: name=nexus daemon_reload=yes enabled=yes state=started - -- name: "Register scripts to be deployed" - set_fact: - nexus_deployed_scripts: - - nexus-blob-backup.sh - - nexus-blob-restore.sh - -- name: "Deploy scripts" - template: - src: "{{ item }}.j2" - dest: "{{ nexus_script_dir }}/{{ item }}" - mode: 0755 - with_items: "{{ nexus_deployed_scripts }}" - -- name: "Symlink scripts to /sbin" - file: - src: "{{ nexus_script_dir }}/{{ item }}" - dest: "/sbin/{{ item }}" - state: link - with_items: "{{ nexus_deployed_scripts }}" + notify: + - systemd-reload + +- block: + - name: "Deploy backup restore script" + template: + src: "nexus-blob-restore.sh.j2" + dest: "{{ nexus_script_dir }}/nexus-blob-restore.sh" + mode: 0755 + - name: "Symlink backup restore script to /sbin" + file: + src: "{{ nexus_script_dir }}/nexus-blob-restore.sh" + dest: "/sbin/nexus-blob-restore.sh" + state: link + when: nexus_backup_configure | bool - name: 'Check if data directory is empty (first-time install)' command: "ls {{ nexus_data_dir }}" register: nexus_data_dir_contents + check_mode: no + changed_when: false - name: Clean cache for upgrade process file: path: "{{ nexus_data_dir }}/clean_cache" state: touch when: nexus_latest_version.changed and nexus_data_dir_contents.stdout != "" + tags: + # hard to run as a handler for time being + - skip_ansible_lint -- name: Reload systemd service configuration - shell: 'systemctl daemon-reload' - -- name: Enable systemd service - shell: 'systemctl enable nexus.service' - -- name: Restart systemd service - shell: 'systemctl restart nexus.service' +- meta: flush_handlers -- name: Waiting for Nexus service to be ready... - wait_for: - path: "{{ nexus_data_dir }}/log/nexus.log" - search_regex: "Started Sonatype Nexus OSS .*" - timeout: 1800 +- name: Enable nexus service and make sure it is started + systemd: + name: nexus.service + enabled: yes + state: started + notify: + - wait-for-nexus + - wait-for-nexus-port -- name: Waiting for nexus to be ready... - wait_for: - port: "{{ nexus_default_port }}" - delay: 5 +- meta: flush_handlers - name: Chown configuration files from {{ nexus_installation_dir }}/nexus-latest/etc back to root file: @@ -228,6 +219,10 @@ group: "root" mode: a=rX,u+w recurse: true + when: chown_config_first_time.changed + tags: + # hard to run as a handler for time being + - skip_ansible_lint - name: Prevent nexus to create any new configuration files in {{ nexus_installation_dir }}/nexus-latest/etc file: @@ -250,54 +245,33 @@ when: nexus_data_dir_contents.stdout != "" no_log: true -- include: declare_script_each.yml - with_items: - - update_admin_password - - setup_ldap - - setup_anonymous_access - - setup_base_url - - setup_capability - - setup_http_proxy - - setup_role - - setup_privilege - - setup_user - - setup_realms - - setup_email - - delete_repo - - delete_blobstore - - create_blobstore - - create_repo_maven_proxy - - create_repo_maven_group - - create_repo_maven_hosted - - create_repo_docker_hosted - - create_repo_docker_proxy - - create_repo_docker_group - - create_repo_pypi_hosted - - create_repo_pypi_proxy - - create_repo_pypi_group - - create_repo_raw_hosted - - create_repo_raw_proxy - - create_repo_raw_group - - create_repo_rubygems_hosted - - create_repo_rubygems_proxy - - create_repo_rubygems_group - - create_repo_bower_hosted - - create_repo_bower_proxy - - create_repo_bower_group - - create_repo_npm_hosted - - create_repo_npm_proxy - - create_repo_npm_group - - create_repo_nuget_hosted - - create_repo_nuget_proxy - - create_repo_nuget_group - - create_repo_gitlfs_hosted - - create_task - -- name: "Config nexus-backup shell cron" - cron: - name: "Backup nexus Blobstore" - minute: "1" - hour: "21" - job: "/sbin/nexus-blob-backup.sh 2>&1 | tee {{ nexus_backup_log }}" - state: present - user: "root" +- name: Create directory to hold current groovy scripts for reference + file: + path: "{{ nexus_data_dir }}/groovy-raw-scripts/current" + state: directory + owner: root + group: root + +- name: Upload new scripts + synchronize: + archive: no + checksum: yes + recursive: yes + delete: yes + mode: push + src: "files/groovy/" + dest: "{{ nexus_data_dir }}/groovy-raw-scripts/new/" + +- name: Sync new scripts to old and get differences + shell: 'rsync -ric {{ nexus_data_dir }}/groovy-raw-scripts/new/ {{ nexus_data_dir }}/groovy-raw-scripts/current/ | cut -d" " -f 2 | sed "s/\.groovy//g"' + register: nexus_groovy_files_changed + check_mode: no + changed_when: false + # simple check on changed files kept on host + # skip ansible lint (we don't want to use synchronize module for this) + args: + warn: false + +- name: Declare new or changed groovy scripts in nexus + include: declare_script_each.yml + with_items: "{{ nexus_groovy_files_changed.stdout_lines}}" diff --git a/tasks/nexus_purge.yml b/tasks/nexus_purge.yml index 758b13b6..caa2a656 100644 --- a/tasks/nexus_purge.yml +++ b/tasks/nexus_purge.yml @@ -1,20 +1,25 @@ --- +- name: Make sure nexus is stopped + debug: + msg: "trigger nexus stop" + changed_when: true + notify: + - nexus-service-stop + +- meta: flush_handlers + - name: "Purge Nexus" file: path: "{{ item }}" state: absent with_items: - - "{{ nexus_data_dir }}" - - "{{ nexus_installation_dir }}/nexus-{{ nexus_version }}" - - "{{ nexus_restore_log }}" -# - "{{ nexus_backup_dir }}" # Optional - -- name: "service stop" - service: - name: nexus - state: stopped + - "{{ nexus_data_dir }}" + - "{{ nexus_installation_dir }}/nexus-{{ nexus_version }}" + - "{{ nexus_restore_log }}" + - "{{ nexus_installation_dir }}/nexus-latest" + # - "{{ nexus_backup_dir }}" # Optional -- name: "remove nexus package" +- name: "remove nexus package if present" package: name: nexus state: absent diff --git a/tasks/selinux-Debian.yml b/tasks/selinux-Debian.yml new file mode 100644 index 00000000..75502149 --- /dev/null +++ b/tasks/selinux-Debian.yml @@ -0,0 +1,10 @@ +--- + +- name: Make sure we have the necessary deb packages available for selinux + apt: + name: "{{ item }}" + update_cache: yes + state: present + with_items: + - python-selinux + - python-semanage diff --git a/tasks/selinux-RedHat.yml b/tasks/selinux-RedHat.yml new file mode 100644 index 00000000..7d4955bd --- /dev/null +++ b/tasks/selinux-RedHat.yml @@ -0,0 +1,9 @@ +--- + +- name: Make sure we have the necessary yum packages available for selinux + yum: + name: "{{ item }}" + state: present + with_items: + - libselinux-python + - libsemanage-python diff --git a/templates/backup.groovy.j2 b/templates/backup.groovy.j2 new file mode 100644 index 00000000..f1aca891 --- /dev/null +++ b/templates/backup.groovy.j2 @@ -0,0 +1,58 @@ +import java.time.LocalDateTime +import org.apache.commons.io.FileUtils +import java.time.format.DateTimeFormatter +import org.sonatype.nexus.scheduling.TaskConfiguration +import org.sonatype.nexus.scheduling.TaskScheduler +import org.sonatype.nexus.scheduling.TaskInfo +import org.sonatype.nexus.scheduling.schedule.Schedule +import java.util.concurrent.TimeUnit + +/** + * This groovy script is meant to be included in a schedulled task in nexus. + * It will perform a full backup of your installation with the following steps. + * 1- Create a blob-backup- folder in directory + * 2- Create a temporary nexus db-backup task to store db backup in /blob-backup-/db + * 3- Start running the temporary task + * 4- Copy all blobstores from /blobs to /blob-backup- + * 5- Eventually wait for the nexus temporary db-backup task to complete + * 6- Delete the nexus temporary db-backup task + */ + + +nexusBackupLogFilePath = "{{ nexus_backup_log }}" +nexusBackupDirPath = "{{ nexus_backup_dir }}" +nexusDataDirPath = "{{ nexus_data_dir }}" + +backupDateString = LocalDateTime.now().format(DateTimeFormatter.ofPattern('YY-MM-dd')) +CurrentBackupDirPath = nexusBackupDirPath+'/blob-backup-'+backupDateString + +backupLog = new File(nexusBackupLogFilePath) + +/** Clear log from previous backup */ +backupLog.text = "" + +try { + backupLog << "Backup directory is "+CurrentBackupDirPath+"\n" + backupLog << "Create a temporary task to backup nexus db in "+CurrentBackupDirPath+"/db\n" + TaskScheduler taskScheduler = container.lookup(TaskScheduler.class.getName()) + TaskConfiguration tempBackupTaskConfiguration = taskScheduler.createTaskConfigurationInstance('db.backup') + tempBackupTaskConfiguration.setName('Temporary db.backup task') + tempBackupTaskConfiguration.setString('location', CurrentBackupDirPath+'/db') + Schedule schedule = taskScheduler.scheduleFactory.manual() + TaskInfo tempBackupTask = taskScheduler.scheduleTask(tempBackupTaskConfiguration, schedule) + + backupLog << "Run the temporay db backup task\n" + tempBackupTask.runNow() + + backupLog << "Copy the blobstores into "+CurrentBackupDirPath+"\n" + FileUtils.copyDirectory(new File(nexusDataDirPath+'/blobs'), new File(CurrentBackupDirPath)) + + backupLog << "Wait for temporary db backup task to finish\n" + while (tempBackupTask.currentState.state != TaskInfo.State.WAITING) { + TimeUnit.SECONDS.sleep(1) + } + backupLog << "Remove temporary task\n" + tempBackupTask.remove() +} catch (Exception e) { + backupLog << e.toString() +} \ No newline at end of file diff --git a/templates/nexus-blob-backup.sh.j2 b/templates/nexus-blob-backup.sh.j2 deleted file mode 100644 index 098f8d9e..00000000 --- a/templates/nexus-blob-backup.sh.j2 +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -# Generated with Ansible vars -MDATE=$(date +%y-%m-%d) -blob_dir="blob-backup-${MDATE}" -backup_dir={{ nexus_backup_dir }} -data_dir={{ nexus_data_dir }} - -systemctl stop nexus -if [ $? != 0 ]; then - echo "Error code: $? Failed to stop nexus service" -else - cp -r ${data_dir}/blobs ${backup_dir}/${blob_dir} - mkdir ${backup_dir}/${blob_dir}/db - for file in $(find ${backup_dir} -name "*${MDATE}*.bak" -type f); do - mv ${file} ${backup_dir}/${blob_dir}/db/; - chown {{ nexus_os_user }}.{{ nexus_os_group }} -Rf ${backup_dir} - done -fi -systemctl restart nexus - diff --git a/tests/syntaxChecking.groovy b/tests/syntaxChecking.groovy index ad6d029d..a5c226a0 100644 --- a/tests/syntaxChecking.groovy +++ b/tests/syntaxChecking.groovy @@ -9,7 +9,7 @@ final File file final CompilationUnit unit final URL url -file = new File('files/groovy/'+args[0]) +file = new File(args[0]) url = file.toURI().toURL() unit = new CompilationUnit( CompilerConfiguration.DEFAULT, diff --git a/tests/run_all_tests.sh b/tests/test_all.sh similarity index 66% rename from tests/run_all_tests.sh rename to tests/test_all.sh index 477e1f75..e3d15f4e 100755 --- a/tests/run_all_tests.sh +++ b/tests/test_all.sh @@ -2,4 +2,4 @@ set -ev ./tests/test_groovySyntax.sh -molecule test +./tests/test_molecule.sh diff --git a/tests/test_groovySyntax.sh b/tests/test_groovySyntax.sh index 6951cb1b..33dda82f 100755 --- a/tests/test_groovySyntax.sh +++ b/tests/test_groovySyntax.sh @@ -1,13 +1,16 @@ -#!/bin/bash +#!/usr/bin/env bash thisScriptPath=`dirname $(readlink -f $0)` -groovyScriptsPath=`dirname $thisScriptPath`/files/groovy +rolePath=`dirname $thisScriptPath` +groovyScriptsPath=${rolePath}/files/groovy groovyChecker=$thisScriptPath/syntaxChecking.groovy exitStatus=0 -echo Checking scripts in files/groovy +echo Checking scripts in files/groovy and template templates/backup.groovy.j2 +scriptFiles=`ls -d -A -1 $groovyScriptsPath/*` +scriptFiles="${scriptFiles} ${rolePath}/templates/backup.groovy.j2" -for script in `ls $groovyScriptsPath`; do +for script in ${scriptFiles} ; do echo Testing groovy syntax for $script groovy $groovyChecker $script if [ ! $? -eq 0 ]; then @@ -21,4 +24,4 @@ done if [ ! $exitStatus -eq 0 ]; then echo Some syntax check have failed. Please fix. Exiting fi -exit $exitStatus \ No newline at end of file +exit $exitStatus diff --git a/tests/test_molecule.sh b/tests/test_molecule.sh new file mode 100755 index 00000000..19599621 --- /dev/null +++ b/tests/test_molecule.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -ev +molecule test diff --git a/vars/blob_vars.yml b/vars/blob_vars.yml index cab0fad6..2a59f6c9 100644 --- a/vars/blob_vars.yml +++ b/vars/blob_vars.yml @@ -1,5 +1,5 @@ --- -nexus_blob_prefix: 'blob-' # Note: Nexus restore - blob name-convention 'blob-*' +nexus_blob_prefix: 'blob-' # Note: Nexus restore - blob name-convention 'blob-*' nexus_blob_names: pypi: blob: '{{ nexus_blob_prefix }}pypi' @@ -19,6 +19,8 @@ nexus_blob_names: blob: '{{ nexus_blob_prefix }}mvn' gitlfs: blob: '{{ nexus_blob_prefix }}gitlfs' + yum: + blob: '{{ nexus_blob_prefix }}yum' nexus_blobstores: @@ -40,3 +42,5 @@ nexus_blobstores: path: "{{ nexus_data_dir }}/blobs/{{ nexus_blob_names.mvn.blob }}" - name: '{{ nexus_blob_prefix }}gitlfs' path: "{{ nexus_data_dir }}/blobs/{{ nexus_blob_names.gitlfs.blob }}" + - name: '{{ nexus_blob_prefix }}yum' + path: "{{ nexus_data_dir }}/blobs/{{ nexus_blob_names.yum.blob }}"