feat: Initial commit

This commit is contained in:
Laur Ivan 2023-09-21 14:58:46 +02:00
commit 5edf4f8d95
32 changed files with 709 additions and 0 deletions

10
.ansible-lint Normal file
View File

@ -0,0 +1,10 @@
---
exclude_paths:
- ./molecule
- ./.travis.yml
- ./.github
parseable: true
skip_list:
- '204'
use_default_rules: true
verbosity: 1

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
*.yml linguist-detectable=true
*.yaml linguist-detectable=true
*.html linguist-detectable=false

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: equinoxel
patreon: laurivan

49
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,49 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:**
[What you expect to happen]
**Actual behavior:**
[What actually happens]
**Reproduces how often:**
[What percentage of the time does it reproduce?]
### Environment
- The release version/s you are using:
- OS:
- Ansible Version:
- Python Version:
- Others:
### Additional Information
[Any additional information, configuration or data that might be necessary to reproduce the issue.]

3
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,3 @@
---
blank_issues_enabled: false

View File

@ -0,0 +1,31 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: enhancement
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Why is this needed?
[A clear and concise description of why do you think this is needed]
### Additional Information
[Any additional information, configuration or data.]

27
.github/ISSUE_TEMPLATE/refactor.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: Refactor
about: Found anything to refactor in this project?
title: "[REFACTOR]"
labels: clean-up
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Link/s to the specific code that needs a refactor (if applicable)
[Links]

View File

@ -0,0 +1,27 @@
---
name: Support Request
about: Support request or question about this project
title: "[SUPPORT]"
labels: question
assignees: ''
---
<!--
PREREQUISITES
Have you read Idealista's Code of Conduct? By filling an Issue, you are expected to comply with it,
including treating everyone with respect: https://github.com/idealista/idealista/blob/master/CODE_OF_CONDUCT.md
Check that your issue isn't already filled: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aidealista
Check that there is not already provided the described functionality
-->
### Description
[Description of the issue]
### Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.

33
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,33 @@
---
issues:
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "pinned"
- "security"
- "good first issue"
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
pulls:
# Number of days of inactivity before a pull request becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale pull request is closed
daysUntilClose: 7
# Comment to post when marking a pull request as stale. Set to `false` to disable
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale pull request. Set to `false` to disable
closeComment: false

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
tests/playbook.retry
tests/.cache
__pycache__
.pytest_cache
.molecule
.cache
.venv
*.iml
.idea
.project
*.pyc
**/.vscode

25
.travis.yml Normal file
View File

@ -0,0 +1,25 @@
---
dist: xenial
language: python
python: "3.9"
os: linux
services:
- docker
install:
- pip install -I pipenv
- pipenv sync
env:
jobs:
- MOLECULE_DISTRO=debian:buster-slim
- MOLECULE_DISTRO=debian:bullseye-slim
script:
- pipenv run molecule test --all
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
email:
if: branch = main
on_success: change
on_failure: always
recipients:
- laur.ivan@gmail.com

33
.yamllint Normal file
View File

@ -0,0 +1,33 @@
---
# Based on ansible-lint config
extends: default
ignore: |
molecule/**/tests/
.venv
.github
.travis.yml
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
empty-lines:
max: 3
level: error
hyphens:
level: error
key-duplicates: enable
line-length: disable
new-lines:
type: unix
truthy: disable

18
CHANGELOG.md Normal file
View File

@ -0,0 +1,18 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a changelog](https://github.com/olivierlacan/keep-a-changelog).
## [Unreleased](https://github.com/equinoxel/ansible-role-unifi-controller/tree/develop)
### Changed
### Added
### Removed
### Fixed
## [X.Y.Z](https://github.com/equinoxel/ansible-role-unifi-controller/tree/X.Y.Z)
### [Full Changelog](https://github.com/equinoxel/ansible-role-unifi-controller/compare/1.0.0...X.Y.Z)
### Changed
*[#<issue_number>](https://github.com/equinoxel/ansible-role-unifi-controller/issues/<issue_number>) \<Change description\>* @\<author\>
## [1.0.0](https://github.com/equinoxel/ansible-role-unifi-controller/tree/1.0.0)
- Initial release

10
LICENSE Normal file
View File

@ -0,0 +1,10 @@
The MIT License (MIT)
=====================
Copyright © 2023 Laur IVAN
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

47
README.md Normal file
View File

@ -0,0 +1,47 @@
# Unifi-Controller Ansible role
This role installs Unifi-Controller via Docker compose.
## Requirements
None
## Role Variables
All variables are listed below (see also `defaults/main.yml`).
```yml
---
```
## Dependencies
You need a machine with docker and docker-compose installed.
## Example Playbook
```yml
- hosts: servers
roles:
- 'laurivan.unifi-controller'
```
## License
This project is licensed under the [MIT](https://opensource.org/licenses/MIT) license - see the [LICENSE](LICENSE) file for details.
![MIT License](https://img.shields.io/badge/license-MIT%20License-brightgreen)
## Author Information
This role was created in 2023 by [Laur Ivan](https://www.laurivan.com).
## Built With
![Ansible](https://img.shields.io/badge/ansible-5.2.0-green.svg)
![Molecule](https://img.shields.io/badge/molecule-3.4.0-green.svg)
![Goss](https://img.shields.io/badge/goss-0.3.16-green.svg)
## Contributing
Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.

42
defaults/main.yml Normal file
View File

@ -0,0 +1,42 @@
---
## General
unifi_image: lscr.io/linuxserver/unifi-controller:latest
unifi_uid: 1000
unifi_gid: 1000
unifi_mem_limit: 1024
unifi_mem_startup: 1024
unifi_volume: "unifi"
unifi_http_port_8443: 8443
unifi_http_port_3478: 3478
unifi_http_port_10001: 10001
unifi_http_port_8080: 8080
# Optional ports
unifi_http_port_1900: 1900
unifi_http_port_8843: 8843
unifi_http_port_8880: 8880
unifi_http_port_6789: 6789
unifi_http_port_5514: 5514
# Unifi-Controller paths
unifi_root_path: /var/local
unifi_data_base: "{{ unifi_root_path }}/unifi-controller"
unifi_config_path: "{{ unifi_root_path }}/conf/unifi-controller"
# Add other paths here to make sure they're created automatically
#
unifi_skeleton_paths:
- "{{ unifi_config_path }}"
# Add more templates to be copied into the config
unifi_configuration_files:
- "docker-compose.yml"
- "env.unifi-controller.conf"
# Documentation
unifi_documentation_link: "https://www.laurivan.com"

2
handlers/main.yml Normal file
View File

@ -0,0 +1,2 @@
---
# Handlers for unifi-controller

26
meta/main.yml Normal file
View File

@ -0,0 +1,26 @@
---
galaxy_info:
author: Laur Ivan (laur.ivan@gmail.com)
namespace: laurivan
role_name: unifi_controller
description: Unifi Controller Role
min_ansible_version: "2.10"
min_ansible_container_version: "2.10"
license: MIT
galaxy_tags:
- unifi
- network
- controller
platforms:
- name: Debian
versions:
- bullseye
- buster
- name: Ubuntu
versions:
- bionic
- focal
- jammy

View File

@ -0,0 +1,27 @@
---
- name: Clean up
hosts: all
gather_facts: true
tasks:
- name: "UNIFI-CONTROLLER | Load the defaults."
ansible.builtin.include_vars:
dir: "../../defaults"
- name: "UNIFI-CONTROLLER | Check if the docker-compose file exists."
ansible.builtin.stat:
path: "{{ unifi_config_path | expanduser | realpath }}/docker-compose.yml"
register: "docker_compose_file"
- name: "UNIFI-CONTROLLER | Remove docker-compose."
community.docker.docker_compose:
project_src: "{{ unifi_config_path | expanduser | realpath }}/"
build: false
state: absent
when: "docker_compose_file.stat.exists"
become: false
- name: "UNIFI-CONTROLLER | Remove the docker-compose file"
ansible.builtin.file:
path: "{{ unifi_config_path | expanduser | realpath }}/docker-compose.yml"
state: "absent"
when: "docker_compose_file.stat.exists"

View File

@ -0,0 +1,5 @@
---
- name: "UNIFI-CONTROLLER | Converge"
hosts: "unifi_group"
roles:
- role: "laurivan.unifi_controller"

View File

@ -0,0 +1,27 @@
---
- name: "UNIFI-CONTROLLER | Destroy"
hosts: "localhost"
connection: "local"
gather_facts: false
no_log: "{{ molecule_no_log }}"
tasks:
# Developer must implement.
- name: "UNIFI-CONTROLLER | Remove the docker image"
community.docker.docker_container:
name: "unifi-controller"
state: "absent"
# Mandatory configuration for Molecule to function.
- name: "UNIFI-CONTROLLER | Populate instance config"
ansible.builtin.set_fact:
instance_conf: {}
- name: "UNIFI-CONTROLLER | Dump instance config"
ansible.builtin.copy:
content: |
# Molecule managed
{{ instance_conf | to_json | from_json | to_yaml }}
dest: "{{ molecule_instance_config }}"
mode: 0600
when: "server.changed | default(false) | bool"

View File

@ -0,0 +1,37 @@
---
dependency:
name: galaxy
options:
ignore-certs: true
ignore-errors: true
role-file: molecule/requirements.yml
requirements-file: molecule/requirements.yml
driver:
name: docker
lint: |
yamllint .
ansible-lint .
platforms:
- name: unifi-controller
groups:
- unifi_group
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos8}-ansible:latest"
privileged: true
pre_build_image: true
capabilities:
- SYS_ADMIN
tmpfs:
- /tmp
- /run
- /run/lock
volumes:
- '/sys/fs/cgroup:/sys/fs/cgroup:ro'
- '/var/run/docker.sock:/tmp/docker_mounted.sock'
command: '/lib/systemd/systemd'
stop_signal: 'RTMIN+3'
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
verifier:
name: ansible

View File

@ -0,0 +1,38 @@
---
- name: "UNIFI-CONTROLLER | Setup the test machine"
hosts: "unifi-controller"
tasks:
- name: "UNIFI-CONTROLLER | Check if /var/run/docker.sock already exists"
ansible.builtin.stat:
path: "/var/run/docker.sock"
register: "docker_sock_stat"
- name: "UNIFI-CONTROLLER | Create docker.sock"
ansible.builtin.raw: touch /var/run/docker.sock
become: true
changed_when: false
when: "not docker_sock_stat.stat.exists"
- name: "UNIFI-CONTROLLER | Move docker.sock from tmp"
ansible.builtin.raw: >
mount --move /tmp/docker_mounted.sock /var/run/docker.sock
become: true
changed_when: false
when: "not docker_sock_stat.stat.exists"
- name: "UNIFI-CONTROLLER | Update apt cache."
ansible.builtin.apt: update_cache=yes cache_valid_time=600
when: "ansible_os_family == 'Debian'"
- name: "UNIFI-CONTROLLER | Install python requests"
ansible.builtin.pip:
name:
- "requests"
- "docker"
- "docker-compose"
- name: "UNIFI-CONTROLLER | Install docker"
vars:
docker_service_manage: false
ansible.builtin.include_role:
name: "geerlingguy.docker"

View File

@ -0,0 +1,4 @@
---
roles:
- "geerlingguy.docker"
collections: []

View File

@ -0,0 +1,12 @@
---
## TODO: Remember to adapt goss tests to your convenience
## Check if ports are really exposed
# port:
# # Check port at IPv6
# # https://github.com/aelsabbahy/goss/issues/177
# tcp6:<port>:
# listening: true
# ip:
# - '::'

View File

@ -0,0 +1,59 @@
---
# This is an example playbook to execute goss tests.
# Tests need distributed to the appropriate ansible host/groups
# prior to execution by `goss validate`.
- name: Verify unifi-controller
hosts:
- "unifi-controller"
become: true
vars:
goss_version: "v0.3.16"
goss_arch: "amd64"
goss_dst: "/usr/local/bin/goss"
goss_sha256sum: "827e354b48f93bce933f5efcd1f00dc82569c42a179cf2d384b040d8a80bfbfb"
goss_url: "https://github.com/aelsabbahy/goss/releases/download/{{ goss_version }}/goss-linux-{{ goss_arch }}"
goss_test_directory:" /tmp"
goss_format: "documentation"
vars_files:
- ../../defaults/main.yml
tasks:
- name: "UNIFI-CONTROLLER | Download and install Goss"
get_url:
url: "{{ goss_url }}"
dest: "{{ goss_dst }}"
checksum: "sha256:{{ goss_sha256sum }}"
mode: 0755
register: "download_goss"
until: "download_goss is succeeded"
retries: 3
- name: "UNIFI-CONTROLLER | Copy Goss tests to remote"
template:
src: "{{ item }}"
dest: "{{ goss_test_directory }}/{{ item | basename }}"
with_fileglob:
- "tests/test_*.yml"
- name: "UNIFI-CONTROLLER | Register test files"
shell: "ls {{ goss_test_directory }}/test_*.yml"
register: "test_files"
- name: "UNIFI-CONTROLLER | Execute Goss tests"
command: "{{ goss_dst }} -g {{ item }} validate --format {{ goss_format }}"
register: "test_results"
with_items: "{{ test_files.stdout_lines }}"
ignore_errors: true
- name: "UNIFI-CONTROLLER | Display details about the Goss results"
debug:
msg: "{{ item.stdout_lines }}"
with_items: "{{ test_results.results }}"
- name: "UNIFI-CONTROLLER | Fail when tests fail"
fail:
msg: "Goss failed to validate"
when: item.rc != 0
with_items: "{{ test_results.results }}"

24
tasks/config.yml Normal file
View File

@ -0,0 +1,24 @@
---
- name: "UNIFI-CONTROLLER | Set up directories"
ansible.builtin.file:
state: directory
path: "{{ item }}"
owner: "{{ ansible_effective_user_id }}"
group: "{{ ansible_effective_group_id }}"
mode: "0750"
with_items:
- "{{ unifi_skeleton_paths }}"
tags:
- unifi_configure
become: true
- name: "UNIFI-CONTROLLER | Write configuration files"
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "{{ unifi_config_path | expanduser | realpath }}/{{ item }}"
mode: '0640'
with_items:
- "{{ unifi_configuration_files }}"
tags:
- unifi_configure

7
tasks/install.yml Normal file
View File

@ -0,0 +1,7 @@
---
- name: "UNIFI-CONTROLLER | Ensure unifi-controller is running"
community.docker.docker_compose:
project_src: "{{ unifi_config_path | expanduser | realpath }}"
build: false
tags:
- unifi_install

11
tasks/main.yml Normal file
View File

@ -0,0 +1,11 @@
---
- name: "UNIFI-CONTROLLER | Configure"
import_tasks: config.yml
tags:
- unifi_configure
- name: "UNIFI-CONTROLLER | Install"
import_tasks: install.yml
tags:
- unifi_install

View File

@ -0,0 +1,40 @@
# unifi-controller docker compose
version: '3.9'
services:
unifi-controller:
image: "{{ unifi_image }}"
container_name: unifi-controller-service
restart: unless-stopped
env_file:
- "{{ unifi_config_path | expanduser }}/env.unifi-controller.conf"
ports:
- "{{ unifi_http_port_8443 }}:8443"
- "{{ unifi_http_port_3478 }}:3478/udp"
- "{{ unifi_http_port_10001 }}:10001/udp"
- "{{ unifi_http_port_8080 }}:8080"
{% if unifi_http_port_1900 is defined -%}
- "{{ unifi_http_port_1900 }}:1900/udp"
{% endif -%}
{% if unifi_http_port_8843 is defined -%}
- "{{ unifi_http_port_8843 }}:8843"
{% endif -%}
{% if unifi_http_port_8880 is defined -%}
- "{{ unifi_http_port_8880 }}:8880"
{% endif -%}
{% if unifi_http_port_6789 is defined -%}
- "{{ unifi_http_port_6789 }}:6789"
{% endif -%}
{% if unifi_http_port_5514 is defined -%}
- "{{ unifi_http_port_5514 }}:5514/udp"
{% endif %}
networks:
- unifi-controller-net
volumes:
- "{{ unifi_volume }}:/config"
volumes:
{{ unifi_volume }}:
networks:
unifi-controller-net: {}

View File

@ -0,0 +1,8 @@
# Add environment variables for unifi-controller here
# Note: This is a .ini file format
PUID={{ unifi_uid }}
PUID={{ unifi_gid }}
MEM_LIMIT={{ unifi_mem_limit }}
MEM_STATUP={{ unifi_mem_startup }}

7
test-requirements.txt Normal file
View File

@ -0,0 +1,7 @@
urllib3==1.26.13
ansible==8.3.0
molecule==6.0.2
docker==6.1.3
molecule-docker==2.1.0
ansible-lint==6.19.0
yamllint==1.32.0