diff --git a/.chglog/CHANGELOG.tpl.md b/.chglog/CHANGELOG.tpl.md deleted file mode 100755 index 72cebbd..0000000 --- a/.chglog/CHANGELOG.tpl.md +++ /dev/null @@ -1,23 +0,0 @@ -# Changelog - -{{ range .Versions -}} -## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }}) - -{{ range .CommitGroups -}} -### {{ .Title }} - -{{ range .Commits -}} -- {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ (regexReplaceAll "Co-\\w*-by.*" .Subject "") | trim }} -{{ end }} -{{ end -}} - -{{- if .NoteGroups -}} -{{ range .NoteGroups -}} -### {{ .Title }} - -{{ range .Notes }} -{{ .Body }} -{{ end }} -{{ end -}} -{{ end -}} -{{ end -}} diff --git a/.chglog/config.yml b/.chglog/config.yml deleted file mode 100755 index c86684b..0000000 --- a/.chglog/config.yml +++ /dev/null @@ -1,25 +0,0 @@ -style: github -template: CHANGELOG.tpl.md -info: - title: CHANGELOG - repository_url: https://github.com/owncloud-ci/drone-ansible -options: - commit_groups: - title_maps: - feat: Features - fix: Bug Fixes - perf: Performance Improvements - refactor: Code Refactoring - chore: Others - test: Testing - ci: CI Pipeline - docs: Documentation - header: - pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$" - pattern_maps: - - Type - - Scope - - Subject - notes: - keywords: - - BREAKING CHANGE diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index f16d676..0000000 --- a/.drone.yml +++ /dev/null @@ -1,187 +0,0 @@ ---- -kind: pipeline -type: docker -name: test - -platform: - os: linux - arch: amd64 - -steps: - - name: lint-editorconfig - image: docker.io/mstruebing/editorconfig-checker - - - name: lint-golang - image: docker.io/golang:1.21 - commands: - - make lint - volumes: - - name: godeps - path: /go - - - name: test - image: docker.io/golang:1.21 - commands: - - make test - volumes: - - name: godeps - path: /go - -volumes: - - name: godeps - temp: {} - -trigger: - ref: - - refs/heads/main - - refs/tags/** - - refs/pull/** - ---- -kind: pipeline -type: docker -name: build-binaries - -platform: - os: linux - arch: amd64 - -steps: - - name: build - image: docker.io/techknowlogick/xgo:go-1.21.x - commands: - - ln -s /drone/src /source - - make release - - - name: executable - image: docker.io/golang:1.21 - commands: - - $(find dist/ -executable -type f -iname ${DRONE_REPO_NAME}-linux-amd64) --help - - - name: changelog - image: quay.io/thegeeklab/git-chglog - commands: - - git fetch -tq - - git-chglog --no-color --no-emoji -o CHANGELOG.md ${DRONE_TAG:---next-tag unreleased unreleased} - - cat CHANGELOG.md - - - name: publish - image: docker.io/plugins/github-release - settings: - api_key: - from_secret: github_token - files: - - dist/* - note: CHANGELOG.md - overwrite: true - title: ${DRONE_TAG} - when: - ref: - - refs/tags/** - -trigger: - ref: - - refs/heads/main - - refs/tags/** - - refs/pull/** - -depends_on: - - test - ---- -kind: pipeline -type: docker -name: build-container - -platform: - os: linux - arch: amd64 - -steps: - - name: security-build - image: docker.io/owncloudci/drone-docker-buildx:2 - settings: - dockerfile: Dockerfile.multiarch - output: type=oci,dest=oci/${DRONE_REPO_NAME},tar=false - repo: owncloudci/${DRONE_REPO_NAME} - - - name: security-scan - image: ghcr.io/aquasecurity/trivy - commands: - - trivy -v - - trivy image --input oci/${DRONE_REPO_NAME} - environment: - TRIVY_EXIT_CODE: 1 - TRIVY_IGNORE_UNFIXED: True - TRIVY_NO_PROGRESS: True - TRIVY_SEVERITY: HIGH,CRITICAL - TRIVY_TIMEOUT: 1m - TRIVY_SKIP_FILES: /opt/pipx/venvs/ansible/lib/**/site-packages/ansible_collections/**/modules/*.py - depends_on: - - security-build - - - name: publish - image: docker.io/owncloudci/drone-docker-buildx:2 - settings: - auto_tag: true - dockerfile: Dockerfile.multiarch - password: - from_secret: docker_password - platforms: - - linux/amd64 - - linux/arm64 - provenance: false - repo: owncloudci/${DRONE_REPO_NAME} - username: - from_secret: docker_username - when: - ref: - - refs/heads/main - - refs/tags/** - depends_on: - - security-scan - -trigger: - ref: - - refs/heads/main - - refs/tags/** - - refs/pull/** - -depends_on: - - test - ---- -kind: pipeline -type: docker -name: notifications - -platform: - os: linux - arch: amd64 - -steps: - - name: pushrm - image: docker.io/chko/docker-pushrm:1 - environment: - DOCKER_PASS: - from_secret: docker_password - DOCKER_USER: - from_secret: docker_username - PUSHRM_FILE: README.md - PUSHRM_SHORT: Drone plugin to provision via Ansible - PUSHRM_TARGET: owncloudci/${DRONE_REPO_NAME} - when: - status: - - success - -trigger: - ref: - - refs/heads/main - - refs/tags/** - status: - - success - - failure - -depends_on: - - build-binaries - - build-container diff --git a/.github/settings.yml b/.github/settings.yml index 6f49363..0f39932 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -1,21 +1,19 @@ ---- repository: - name: drone-ansible - description: Drone plugin to provision via Ansible - homepage: https://hub.docker.com/r/owncloudci/drone-ansible - topics: drone, drone-plugin + name: wp-ansible + description: Woodpecker CI plugin to manage infrastructure with Ansible + homepage: https://woodpecker-plugins.geekdocs.de/plugins/wp-ansible + topics: woodpecker-ci, woodpecker, woodpecker-plugin private: false has_issues: true - has_projects: false has_wiki: false - has_downloads: false + has_downloads: true default_branch: main allow_squash_merge: true - allow_merge_commit: false - allow_rebase_merge: false + allow_merge_commit: true + allow_rebase_merge: true labels: - name: bug @@ -46,10 +44,6 @@ labels: color: ffffff description: This will not be worked on -teams: - - name: bot - permission: write - branches: - name: main protection: @@ -57,11 +51,21 @@ branches: required_status_checks: strict: false contexts: - - continuous-integration/drone/pr + - ci/woodpecker/pr/test + - ci/woodpecker/pr/build-package + - ci/woodpecker/pr/build-container + - ci/woodpecker/pr/docs enforce_admins: false + required_linear_history: true + restrictions: null + - name: docs + protection: + required_pull_request_reviews: null + required_status_checks: null + enforce_admins: true + required_linear_history: true restrictions: - apps: - - renovate + apps: [] users: [] teams: - bot diff --git a/.gitignore b/.gitignore index 1f61343..ef8ceba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -/release/ -/dist/ -/drone-ansible* +/dist +/release +/wp-ansible* coverage.out CHANGELOG.md diff --git a/.gitsv/config.yml b/.gitsv/config.yml new file mode 100644 index 0000000..acaf506 --- /dev/null +++ b/.gitsv/config.yml @@ -0,0 +1,47 @@ +--- +version: "1.1" + +versioning: + update-major: [] + update-minor: [feat] + update-patch: [fix, perf, refactor, chore, test, ci, docs] + +tag: + pattern: "v%d.%d.%d" + +release-notes: + sections: + - name: Features + commit-types: [feat] + section-type: commits + - name: Bug Fixes + commit-types: [fix] + section-type: commits + - name: Performance Improvements + commit-types: [perf] + section-type: commits + - name: Code Refactoring + commit-types: [refactor] + section-type: commits + - name: Others + commit-types: [chore] + section-type: commits + - name: Testing + commit-types: [test] + section-type: commits + - name: CI Pipeline + commit-types: [ci] + section-type: commits + - name: Documentation + commit-types: [docs] + section-type: commits + - name: BREAKING CHANGES + section-type: breaking-changes + +commit-message: + footer: + issue: + key: issue + add-value-prefix: "#" + issue: + regex: "#?[0-9]+" diff --git a/.golangci.yml b/.golangci.yml index 74658e8..a962256 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,4 +1,3 @@ ---- linters: enable-all: false disable-all: true @@ -72,6 +71,9 @@ linters: - promlinter - reassign - revive + # - rowserrcheck + # - sqlclosecheck + # - structcheck - stylecheck - tagliatelle - tenv @@ -81,13 +83,10 @@ linters: - unconvert - unparam - usestdlibvars + # - wastedassign - whitespace - wsl - ## not working in golangci yet - # - rowserrcheck - # - sqlclosecheck - # - structcheck - # - wastedassign + - zerologlint fast: false run: @@ -96,3 +95,9 @@ run: linters-settings: gofumpt: extra-rules: true + ireturn: + allow: + - anon + - error + - empty + - stdlib diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 0000000..b59a114 --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,6 @@ +--- +default: True +MD013: False +MD041: False +MD004: + style: dash diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..135c35d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +*.tpl.md +LICENSE diff --git a/.woodpecker/build-container.yml b/.woodpecker/build-container.yml new file mode 100644 index 0000000..aeab61e --- /dev/null +++ b/.woodpecker/build-container.yml @@ -0,0 +1,66 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + dryrun: + image: quay.io/thegeeklab/wp-docker-buildx:2.0.0 + settings: + containerfile: Containerfile.multiarch + dry_run: true + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: ${CI_REPO} + when: + - event: [pull_request] + + publish-dockerhub: + group: container + image: quay.io/thegeeklab/wp-docker-buildx:2.0.0 + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: docker_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: ${CI_REPO} + username: + from_secret: docker_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + + publish-quay: + group: container + image: quay.io/thegeeklab/wp-docker-buildx:2.0.0 + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: quay_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + registry: quay.io + repo: quay.io/${CI_REPO} + username: + from_secret: quay_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +depends_on: + - test diff --git a/.woodpecker/build-package.yml b/.woodpecker/build-package.yml new file mode 100644 index 0000000..8415e0c --- /dev/null +++ b/.woodpecker/build-package.yml @@ -0,0 +1,42 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + build: + image: docker.io/techknowlogick/xgo:go-1.21.x + commands: + - ln -s $(pwd) /source + - make release + + executable: + image: quay.io/thegeeklab/alpine-tools + commands: + - $(find dist/ -executable -type f -iname ${CI_REPO_NAME}-linux-amd64) --help + + changelog: + image: quay.io/thegeeklab/git-sv + commands: + - git fetch --depth=2147483647 + - git sv current-version + - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md + - cat CHANGELOG.md + + publish-github: + image: docker.io/plugins/github-release + settings: + api_key: + from_secret: github_token + files: + - dist/* + note: CHANGELOG.md + overwrite: true + title: ${CI_COMMIT_TAG} + when: + - event: [tag] + +depends_on: + - test diff --git a/.woodpecker/docs.yml b/.woodpecker/docs.yml new file mode 100644 index 0000000..aa98bed --- /dev/null +++ b/.woodpecker/docs.yml @@ -0,0 +1,79 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + markdownlint: + image: quay.io/thegeeklab/markdownlint-cli + group: test + commands: + - markdownlint 'README.md' 'CONTRIBUTING.md' + + spellcheck: + image: quay.io/thegeeklab/alpine-tools + group: test + commands: + - spellchecker --files '_docs/**/*.md' 'README.md' 'CONTRIBUTING.md' -d .dictionary -p spell indefinite-article syntax-urls + environment: + FORCE_COLOR: "true" + + link-validation: + image: docker.io/lycheeverse/lychee + group: test + commands: + - lychee --no-progress --format detailed _docs/content README.md + + publish: + image: quay.io/thegeeklab/wp-git-action + settings: + action: + - pages + author_email: bot@thegeeklab.de + author_name: thegeeklab-bot + branch: docs + message: "[skip ci] auto-update documentation" + netrc_password: + from_secret: github_token + pages_directory: _docs/ + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + + pushrm-dockerhub: + image: docker.io/chko/docker-pushrm:1 + secrets: + - source: docker_password + target: DOCKER_PASS + - source: docker_username + target: DOCKER_USER + environment: + PUSHRM_FILE: README.md + PUSHRM_SHORT: Woodpecker CI plugin to manage infrastructure with Ansible + PUSHRM_TARGET: ${CI_REPO} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + + pushrm-quay: + image: docker.io/chko/docker-pushrm:1 + secrets: + - source: quay_token + target: APIKEY__QUAY_IO + environment: + PUSHRM_FILE: README.md + PUSHRM_TARGET: quay.io/${CI_REPO} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + +depends_on: + - build-package + - build-container diff --git a/.woodpecker/notify.yml b/.woodpecker/notify.yml new file mode 100644 index 0000000..a851904 --- /dev/null +++ b/.woodpecker/notify.yml @@ -0,0 +1,26 @@ +--- +when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +runs_on: [success, failure] + +steps: + matrix: + image: quay.io/thegeeklab/wp-matrix + settings: + homeserver: + from_secret: matrix_homeserver + password: + from_secret: matrix_password + roomid: + from_secret: matrix_roomid + username: + from_secret: matrix_username + when: + - status: [success, failure] + +depends_on: + - docs diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml new file mode 100644 index 0000000..abd3763 --- /dev/null +++ b/.woodpecker/test.yml @@ -0,0 +1,17 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + lint: + image: docker.io/library/golang:1.21 + commands: + - make lint + + test: + image: docker.io/library/golang:1.21 + commands: + - make test diff --git a/Dockerfile.multiarch b/Containerfile.multiarch similarity index 67% rename from Dockerfile.multiarch rename to Containerfile.multiarch index 035d282..a1d6590 100644 --- a/Dockerfile.multiarch +++ b/Containerfile.multiarch @@ -10,12 +10,12 @@ RUN make build FROM docker.io/python:3.12-alpine@sha256:c793b92fd9e0e2a0b611756788a033d569ca864b733461c8fb30cfd14847dbcf -LABEL maintainer="ownCloud DevOps " -LABEL org.opencontainers.image.authors="ownCloud DevOps " -LABEL org.opencontainers.image.title="drone-ansible" -LABEL org.opencontainers.image.url="https://github.com/owncloud-ci/drone-ansible" -LABEL org.opencontainers.image.source="https://github.com/owncloud-ci/drone-ansible" -LABEL org.opencontainers.image.documentation="https://github.com/owncloud-ci/drone-ansible" +LABEL maintainer="Robert Kaussow " +LABEL org.opencontainers.image.authors="Robert Kaussow " +LABEL org.opencontainers.image.title="wp-ansible" +LABEL org.opencontainers.image.url="https://github.com/thegeeklab/wp-ansible" +LABEL org.opencontainers.image.source="https://github.com/thegeeklab/wp-ansible" +LABEL org.opencontainers.image.documentation="https://github.com/thegeeklab/wp-ansible" ARG TARGETOS ARG TARGETARCH @@ -35,5 +35,5 @@ RUN apk --update add --virtual .build-deps python3-dev libffi-dev build-base && rm -rf /tmp/* && \ rm -rf /root/.cache/ -COPY --from=build /src/dist/drone-ansible /bin/drone-ansible -ENTRYPOINT ["/bin/drone-ansible"] +COPY --from=build /src/dist/wp-ansible /bin/wp-ansible +ENTRYPOINT ["/bin/wp-ansible"] diff --git a/LICENSE b/LICENSE index e1f657b..7db554f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -175,7 +176,18 @@ END OF TERMS AND CONDITIONS - Copyright 2022 ownCloud GmbH + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 Robert Kaussow Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index 0fb02bb..1f6915f 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,11 @@ GOFUMPT_PACKAGE_VERSION := v0.5.0 # renovate: datasource=github-releases depName=golangci/golangci-lint GOLANGCI_LINT_PACKAGE_VERSION := v1.55.2 -SHELL := bash -NAME := drone-ansible -IMPORT := github.com/owncloud-ci/$(NAME) +EXECUTABLE := wp-ansible + DIST := dist DIST_DIRS := $(DIST) +IMPORT := github.com/thegeeklab/$(EXECUTABLE) GO ?= go CWD ?= $(shell pwd) @@ -19,14 +19,20 @@ GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(G XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest +GENERATE ?= XGO_VERSION := go-1.21.x XGO_TARGETS ?= linux/amd64,linux/arm64 +TARGETOS ?= linux +TARGETARCH ?= amd64 +ifneq ("$(TARGETVARIANT)","") +GOARM ?= $(subst v,,$(TARGETVARIANT)) +endif TAGS ?= netgo ifndef VERSION - ifneq ($(DRONE_TAG),) - VERSION ?= $(subst v,,$(DRONE_TAG)) + ifneq ($(CI_COMMIT_TAG),) + VERSION ?= $(subst v,,$(CI_COMMIT_TAG)) else VERSION ?= $(shell git rev-parse --short HEAD) endif @@ -39,12 +45,12 @@ endif LDFLAGS += -s -w -X "main.BuildVersion=$(VERSION)" -X "main.BuildDate=$(DATE)" .PHONY: all -all: build +all: clean build .PHONY: clean clean: $(GO) clean -i ./... - @rm -rf $(DIST_DIRS) + rm -rf $(DIST_DIRS) .PHONY: fmt fmt: @@ -57,28 +63,32 @@ golangci-lint: .PHONY: lint lint: golangci-lint +.PHONY: generate +generate: + $(GO) generate $(GENERATE) + .PHONY: test test: - $(GO) run $(GOTESTSUM_PACKAGE) -- -coverprofile=coverage.out $(PACKAGES) + $(GO) run $(GOTESTSUM_PACKAGE) --no-color=false -- -coverprofile=coverage.out $(PACKAGES) .PHONY: build -build: $(DIST)/$(NAME) +build: $(DIST)/$(EXECUTABLE) -$(DIST)/$(NAME): $(SOURCES) - $(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(NAME) +$(DIST)/$(EXECUTABLE): $(SOURCES) + GOOS=$(TARGETOS) GOARCH=$(TARGETARCH) GOARM=$(GOARM) $(GO) build -v -tags '$(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -o $@ ./cmd/$(EXECUTABLE) $(DIST_DIRS): - @mkdir -p $(DIST_DIRS) + mkdir -p $(DIST_DIRS) .PHONY: xgo xgo: | $(DIST_DIRS) - $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -v -ldflags '-extldflags "-static" $(LDFLAGS)' -tags '$(TAGS)' -targets '$(XGO_TARGETS)' -out $(NAME) --pkg cmd/$(NAME) . + $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -v -ldflags '-extldflags "-static" $(LDFLAGS)' -tags '$(TAGS)' -targets '$(XGO_TARGETS)' -out $(EXECUTABLE) --pkg cmd/$(EXECUTABLE) . cp /build/* $(CWD)/$(DIST) ls -l $(CWD)/$(DIST) .PHONY: checksum checksum: - cd $(DIST); $(foreach file,$(wildcard $(DIST)/$(NAME)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) + cd $(DIST); $(foreach file,$(wildcard $(DIST)/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;) ls -l $(CWD)/$(DIST) .PHONY: release diff --git a/README.md b/README.md index d903a5e..985fa5e 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,21 @@ -# drone-ansible +# wp-ansible -[![Build Status](https://drone.owncloud.com/api/badges/owncloud-ci/drone-ansible/status.svg)](https://drone.owncloud.com/owncloud-ci/drone-ansible) -[![Docker Hub](https://img.shields.io/docker/v/owncloudci/drone-ansible?logo=docker&label=dockerhub&sort=semver&logoColor=white)](https://hub.docker.com/r/owncloudci/drone-ansible) -[![GitHub contributors](https://img.shields.io/github/contributors/owncloud-ci/drone-ansible)](https://github.com/owncloud-ci/drone-ansible/graphs/contributors) -[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/owncloud-ci/drone-ansible) -[![License: Apache-2.0](https://img.shields.io/github/license/owncloud-ci/drone-ansible)](https://github.com/owncloud-ci/drone-ansible/blob/main/LICENSE) +Woodpecker CI plugin to manage infrastructure with Ansible -Drone plugin to provision infrastructure with [Ansible](https://www.ansible.com/). +[![Build Status](https://ci.thegeeklab.de/api/badges/thegeeklab/wp-ansible/status.svg)](https://ci.thegeeklab.de/repos/thegeeklab/wp-ansible) +[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/wp-ansible) +[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/wp-ansible) +[![Go Report Card](https://goreportcard.com/badge/github.com/thegeeklab/wp-ansible)](https://goreportcard.com/report/github.com/thegeeklab/wp-ansible) +[![GitHub contributors](https://img.shields.io/github/contributors/thegeeklab/wp-ansible)](https://github.com/thegeeklab/wp-ansible/graphs/contributors) +[![Source: GitHub](https://img.shields.io/badge/source-github-blue.svg?logo=github&logoColor=white)](https://github.com/thegeeklab/wp-ansible) +[![License: Apache-2.0](https://img.shields.io/github/license/thegeeklab/wp-ansible)](https://github.com/thegeeklab/wp-ansible/blob/main/LICENSE) -## Versioning +Woodpecker CI plugin to manage infrastructure with [Ansible](https://www.ansible.com/). You can find the full documentation at [https://woodpecker-plugins.geekdocs.de](https://woodpecker-plugins.geekdocs.de/plugins/wp-ansible). -The tags follow the major version of Docker, e.g. `8`, and the minor and patch parts reflect the `version` of the plugin. A full example would be `8.5.2`. Minor versions can introduce breaking changes, while patch versions can be considered non-breaking. +## Contributors -## Usage - -```yaml -kind: pipeline -type: docker -name: default - -steps: - - name: ansible - image: owncloudci/drone-ansible - settings: - playbook: deployment/playbook.yml - private_key: - from_secret: ansible_private_key - inventory: deployment/hosts.yml -``` - -## Build - -Build the binary with the following command: - -```console -make build -``` - -Build the Docker image with the following command: - -```console -docker build --file Dockerfile.multiarch --tag owncloudci/drone-ansible . -``` - -## Test - -```console -docker run --rm \ - -e PLUGIN_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" \ - -e PLUGIN_PLAYBOOK="deployment/playbook.yml" \ - -e PLUGIN_INVENTORY="deployment/hosts.yml" \ - -v $(pwd):$(pwd) \ - -w $(pwd) \ - owncloudci/drone-ansible --dry-run -``` - -## Releases - -Create and push the new tag to trigger the CI release process: - -```console -git tag v2.10.3 -git push origin v2.10.3 -``` +Special thanks to all [contributors](https://github.com/thegeeklab/wp-ansible/graphs/contributors). If you would like to contribute, please see the [instructions](https://github.com/thegeeklab/wp-ansible/blob/main/CONTRIBUTING.md). ## License -This project is licensed under the Apache 2.0 License - see the [LICENSE](https://github.com/owncloud-ci/drone-ansible/blob/main/LICENSE) file for details. - -## Copyright - -```text -Copyright (c) 2022 ownCloud GmbH -``` +This project is licensed under the Apache-2.0 License - see the [LICENSE](https://github.com/thegeeklab/wp-ansible/blob/main/LICENSE) file for details. diff --git a/cmd/drone-ansible/config.go b/cmd/drone-ansible/config.go index 511edb8..141b5a5 100644 --- a/cmd/drone-ansible/config.go +++ b/cmd/drone-ansible/config.go @@ -1,120 +1,138 @@ package main import ( - "github.com/owncloud-ci/drone-ansible/plugin" + "github.com/thegeeklab/wp-ansible/plugin" "github.com/urfave/cli/v2" ) // settingsFlags has the cli.Flags for the plugin.Settings. -func settingsFlags(settings *plugin.Settings) []cli.Flag { +func settingsFlags(settings *plugin.Settings, category string) []cli.Flag { return []cli.Flag{ &cli.StringFlag{ Name: "requirements", Usage: "path to python requirements", EnvVars: []string{"PLUGIN_REQUIREMENTS"}, Destination: &settings.Requirements, + Category: category, }, &cli.StringFlag{ Name: "galaxy", Usage: "path to galaxy requirements", EnvVars: []string{"PLUGIN_GALAXY"}, Destination: &settings.Galaxy, + Category: category, }, &cli.StringSliceFlag{ Name: "inventory", Usage: "specify inventory host path", EnvVars: []string{"PLUGIN_INVENTORY", "PLUGIN_INVENTORIES"}, Destination: &settings.Inventories, + Category: category, }, &cli.StringSliceFlag{ Name: "playbook", Usage: "list of playbooks to apply", EnvVars: []string{"PLUGIN_PLAYBOOK", "PLUGIN_PLAYBOOKS"}, Destination: &settings.Playbooks, + Category: category, }, &cli.StringFlag{ Name: "limit", Usage: "further limit selected hosts to an additional pattern", EnvVars: []string{"PLUGIN_LIMIT"}, Destination: &settings.Limit, + Category: category, }, &cli.StringFlag{ Name: "skip-tags", Usage: "only run plays and tasks whose tags do not match", EnvVars: []string{"PLUGIN_SKIP_TAGS"}, Destination: &settings.SkipTags, + Category: category, }, &cli.StringFlag{ Name: "start-at-task", Usage: "start the playbook at the task matching this name", EnvVars: []string{"PLUGIN_START_AT_TASK"}, Destination: &settings.StartAtTask, + Category: category, }, &cli.StringFlag{ Name: "tags", Usage: "only run plays and tasks tagged with these values", EnvVars: []string{"PLUGIN_TAGS"}, Destination: &settings.Tags, + Category: category, }, &cli.StringSliceFlag{ Name: "extra-vars", Usage: "set additional variables as key=value", EnvVars: []string{"PLUGIN_EXTRA_VARS", "ANSIBLE_EXTRA_VARS"}, Destination: &settings.ExtraVars, + Category: category, }, &cli.StringSliceFlag{ Name: "module-path", Usage: "prepend paths to module library", EnvVars: []string{"PLUGIN_MODULE_PATH"}, Destination: &settings.ModulePath, + Category: category, }, &cli.BoolFlag{ Name: "check", Usage: "run a check, do not apply any changes", EnvVars: []string{"PLUGIN_CHECK"}, Destination: &settings.Check, + Category: category, }, &cli.BoolFlag{ Name: "diff", Usage: "show the differences, may print secrets", EnvVars: []string{"PLUGIN_DIFF"}, Destination: &settings.Diff, + Category: category, }, &cli.BoolFlag{ Name: "flush-cache", Usage: "clear the fact cache for every host in inventory", EnvVars: []string{"PLUGIN_FLUSH_CACHE"}, Destination: &settings.FlushCache, + Category: category, }, &cli.BoolFlag{ Name: "force-handlers", Usage: "run handlers even if a task fails", EnvVars: []string{"PLUGIN_FORCE_HANDLERS"}, Destination: &settings.ForceHandlers, + Category: category, }, &cli.BoolFlag{ Name: "list-hosts", Usage: "outputs a list of matching hosts", EnvVars: []string{"PLUGIN_LIST_HOSTS"}, Destination: &settings.ListHosts, + Category: category, }, &cli.BoolFlag{ Name: "list-tags", Usage: "list all available tags", EnvVars: []string{"PLUGIN_LIST_TAGS"}, Destination: &settings.ListTags, + Category: category, }, &cli.BoolFlag{ Name: "list-tasks", Usage: "list all tasks that would be executed", EnvVars: []string{"PLUGIN_LIST_TASKS"}, Destination: &settings.ListTasks, + Category: category, }, &cli.BoolFlag{ Name: "syntax-check", Usage: "perform a syntax check on the playbook", EnvVars: []string{"PLUGIN_SYNTAX_CHECK"}, Destination: &settings.SyntaxCheck, + Category: category, }, &cli.IntFlag{ Name: "forks", @@ -122,90 +140,105 @@ func settingsFlags(settings *plugin.Settings) []cli.Flag { EnvVars: []string{"PLUGIN_FORKS"}, Value: plugin.AnsibleForksDefault, Destination: &settings.Forks, + Category: category, }, &cli.StringFlag{ Name: "vault-id", Usage: "the vault identity to use", EnvVars: []string{"PLUGIN_VAULT_ID", "ANSIBLE_VAULT_ID"}, Destination: &settings.VaultID, + Category: category, }, &cli.StringFlag{ Name: "vault-password", Usage: "the vault password to use", EnvVars: []string{"PLUGIN_VAULT_PASSWORD", "ANSIBLE_VAULT_PASSWORD"}, Destination: &settings.VaultPassword, + Category: category, }, &cli.IntFlag{ Name: "verbose", Usage: "level of verbosity, 0 up to 4", EnvVars: []string{"PLUGIN_VERBOSE"}, Destination: &settings.Verbose, + Category: category, }, &cli.StringFlag{ Name: "private-key", Usage: "use this key to authenticate the connection", EnvVars: []string{"PLUGIN_PRIVATE_KEY", "ANSIBLE_PRIVATE_KEY"}, Destination: &settings.PrivateKey, + Category: category, }, &cli.StringFlag{ Name: "user", Usage: "connect as this user", EnvVars: []string{"PLUGIN_USER", "ANSIBLE_USER"}, Destination: &settings.User, + Category: category, }, &cli.StringFlag{ Name: "connection", Usage: "connection type to use", EnvVars: []string{"PLUGIN_CONNECTION"}, Destination: &settings.Connection, + Category: category, }, &cli.IntFlag{ Name: "timeout", Usage: "override the connection timeout in seconds", EnvVars: []string{"PLUGIN_TIMEOUT"}, Destination: &settings.Timeout, + Category: category, }, &cli.StringFlag{ Name: "ssh-common-args", Usage: "specify common arguments to pass to sftp/scp/ssh", EnvVars: []string{"PLUGIN_SSH_COMMON_ARGS"}, Destination: &settings.SSHCommonArgs, + Category: category, }, &cli.StringFlag{ Name: "sftp-extra-args", Usage: "specify extra arguments to pass to sftp only", EnvVars: []string{"PLUGIN_SFTP_EXTRA_ARGS"}, Destination: &settings.SFTPExtraArgs, + Category: category, }, &cli.StringFlag{ Name: "scp-extra-args", Usage: "specify extra arguments to pass to scp only", EnvVars: []string{"PLUGIN_SCP_EXTRA_ARGS"}, Destination: &settings.SCPExtraArgs, + Category: category, }, &cli.StringFlag{ Name: "ssh-extra-args", Usage: "specify extra arguments to pass to ssh only", EnvVars: []string{"PLUGIN_SSH_EXTRA_ARGS"}, Destination: &settings.SSHExtraArgs, + Category: category, }, &cli.BoolFlag{ Name: "become", Usage: "run operations with become", EnvVars: []string{"PLUGIN_BECOME"}, Destination: &settings.Become, + Category: category, }, &cli.StringFlag{ Name: "become-method", Usage: "privilege escalation method to use", EnvVars: []string{"PLUGIN_BECOME_METHOD", "ANSIBLE_BECOME_METHOD"}, Destination: &settings.BecomeMethod, + Category: category, }, &cli.StringFlag{ Name: "become-user", Usage: "run operations as this user", EnvVars: []string{"PLUGIN_BECOME_USER", "ANSIBLE_BECOME_USER"}, Destination: &settings.BecomeUser, + Category: category, }, } } diff --git a/cmd/drone-ansible/main.go b/cmd/drone-ansible/main.go index 75b861b..4b0877a 100644 --- a/cmd/drone-ansible/main.go +++ b/cmd/drone-ansible/main.go @@ -2,14 +2,10 @@ package main import ( "fmt" - "os" - "github.com/joho/godotenv" - "github.com/owncloud-ci/drone-ansible/plugin" - "github.com/urfave/cli/v2" + "github.com/thegeeklab/wp-ansible/plugin" - "github.com/drone-plugins/drone-plugin-lib/errors" - "github.com/drone-plugins/drone-plugin-lib/urfave" + wp "github.com/thegeeklab/wp-plugin-go/plugin" ) //nolint:gochecknoglobals @@ -20,56 +16,13 @@ var ( func main() { settings := &plugin.Settings{} - - if _, err := os.Stat("/run/drone/env"); err == nil { - _ = godotenv.Overload("/run/drone/env") + options := wp.Options{ + Name: "wp-ansible", + Description: "Manage infrastructure with Ansible", + Version: BuildVersion, + VersionMetadata: fmt.Sprintf("date=%s", BuildDate), + Flags: settingsFlags(settings, wp.FlagsPluginCategory), } - cli.VersionPrinter = func(c *cli.Context) { - fmt.Printf("%s version=%s date=%s\n", c.App.Name, c.App.Version, BuildDate) - } - - app := &cli.App{ - Name: "drone-ansible", - Usage: "provision infrastructure with Ansible", - Version: BuildVersion, - Flags: append(settingsFlags(settings), urfave.Flags()...), - Action: run(settings), - } - - if err := app.Run(os.Args); err != nil { - errors.HandleExit(err) - } -} - -func run(settings *plugin.Settings) cli.ActionFunc { - return func(ctx *cli.Context) error { - urfave.LoggingFromContext(ctx) - - plugin := plugin.New( - *settings, - urfave.PipelineFromContext(ctx), - urfave.NetworkFromContext(ctx), - ) - - if err := plugin.Validate(); err != nil { - //nolint:errorlint - if e, ok := err.(errors.ExitCoder); ok { - return e - } - - return errors.ExitMessagef("validation failed: %w", err) - } - - if err := plugin.Execute(); err != nil { - //nolint:errorlint - if e, ok := err.(errors.ExitCoder); ok { - return e - } - - return errors.ExitMessagef("execution failed: %w", err) - } - - return nil - } + plugin.New(options, settings).Run() } diff --git a/go.mod b/go.mod index 5a921f3..139a5bc 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,20 @@ -module github.com/owncloud-ci/drone-ansible +module github.com/thegeeklab/wp-ansible go 1.21 require ( - github.com/drone-plugins/drone-plugin-lib v0.4.2 - github.com/joho/godotenv v1.5.1 + github.com/thegeeklab/wp-plugin-go v1.2.0 github.com/urfave/cli/v2 v2.26.0 golang.org/x/sys v0.15.0 ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/rs/zerolog v1.31.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect + golang.org/x/net v0.19.0 // indirect ) diff --git a/go.sum b/go.sum index b838c48..2a2d024 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,31 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/drone-plugins/drone-plugin-lib v0.4.2 h1:EiJ3Kco6ypP5noBQqVt1bBbuO1eUAumtPvLTX/NVAYg= -github.com/drone-plugins/drone-plugin-lib v0.4.2/go.mod h1:KwCu92jFjHV3xv2hu5Qg/8zBNvGwbhoJDQw/EwnTvoM= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= +github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/thegeeklab/wp-plugin-go v1.2.0 h1:ZvwfIIqT6UlclUhz3IYvHf+Jjam/orCaOgdTO+zbUiI= +github.com/thegeeklab/wp-plugin-go v1.2.0/go.mod h1:8DfPtNMelj6rJxBru3r8CAE4PMg6HsbxcRuE2Mu1tpw= github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/plugin/ansible.go b/plugin/ansible.go index 531500a..0b90790 100644 --- a/plugin/ansible.go +++ b/plugin/ansible.go @@ -51,7 +51,7 @@ func (p *Plugin) privateKey() error { return fmt.Errorf("failed to create private key file: %w", err) } - if _, err := tmpfile.Write([]byte(p.settings.PrivateKey)); err != nil { + if _, err := tmpfile.Write([]byte(p.Settings.PrivateKey)); err != nil { return fmt.Errorf("failed to write private key file: %w", err) } @@ -59,7 +59,7 @@ func (p *Plugin) privateKey() error { return fmt.Errorf("failed to close private key file: %w", err) } - p.settings.PrivateKeyFile = tmpfile.Name() + p.Settings.PrivateKeyFile = tmpfile.Name() return nil } @@ -70,7 +70,7 @@ func (p *Plugin) vaultPass() error { return fmt.Errorf("failed to create vault password file: %w", err) } - if _, err := tmpfile.Write([]byte(p.settings.VaultPassword)); err != nil { + if _, err := tmpfile.Write([]byte(p.Settings.VaultPassword)); err != nil { return fmt.Errorf("failed to write vault password file: %w", err) } @@ -78,7 +78,7 @@ func (p *Plugin) vaultPass() error { return fmt.Errorf("failed to close vault password file: %w", err) } - p.settings.VaultPasswordFile = tmpfile.Name() + p.Settings.VaultPasswordFile = tmpfile.Name() return nil } @@ -86,7 +86,7 @@ func (p *Plugin) vaultPass() error { func (p *Plugin) playbooks() error { var playbooks []string - for _, p := range p.settings.Playbooks.Value() { + for _, p := range p.Settings.Playbooks.Value() { files, err := filepath.Glob(p) if err != nil { playbooks = append(playbooks, p) @@ -101,7 +101,7 @@ func (p *Plugin) playbooks() error { return ErrAnsiblePlaybookNotFound } - p.settings.Playbooks = *cli.NewStringSlice(playbooks...) + p.Settings.Playbooks = *cli.NewStringSlice(playbooks...) return nil } @@ -122,7 +122,7 @@ func (p *Plugin) requirementsCommand() *execabs.Cmd { "install", "--upgrade", "--requirement", - p.settings.Requirements, + p.Settings.Requirements, } return execabs.Command( @@ -136,11 +136,11 @@ func (p *Plugin) galaxyCommand() *execabs.Cmd { "install", "--force", "--role-file", - p.settings.Galaxy, + p.Settings.Galaxy, } - if p.settings.Verbose > 0 { - args = append(args, fmt.Sprintf("-%s", strings.Repeat("v", p.settings.Verbose))) + if p.Settings.Verbose > 0 { + args = append(args, fmt.Sprintf("-%s", strings.Repeat("v", p.Settings.Verbose))) } return execabs.Command( @@ -155,25 +155,25 @@ func (p *Plugin) ansibleCommand(inventory string) *execabs.Cmd { inventory, } - if len(p.settings.ModulePath.Value()) > 0 { - args = append(args, "--module-path", strings.Join(p.settings.ModulePath.Value(), ":")) + if len(p.Settings.ModulePath.Value()) > 0 { + args = append(args, "--module-path", strings.Join(p.Settings.ModulePath.Value(), ":")) } - if p.settings.VaultID != "" { - args = append(args, "--vault-id", p.settings.VaultID) + if p.Settings.VaultID != "" { + args = append(args, "--vault-id", p.Settings.VaultID) } - if p.settings.VaultPasswordFile != "" { - args = append(args, "--vault-password-file", p.settings.VaultPasswordFile) + if p.Settings.VaultPasswordFile != "" { + args = append(args, "--vault-password-file", p.Settings.VaultPasswordFile) } - for _, v := range p.settings.ExtraVars.Value() { + for _, v := range p.Settings.ExtraVars.Value() { args = append(args, "--extra-vars", v) } - if p.settings.ListHosts { + if p.Settings.ListHosts { args = append(args, "--list-hosts") - args = append(args, p.settings.Playbooks.Value()...) + args = append(args, p.Settings.Playbooks.Value()...) return execabs.Command( ansiblePlaybookBin, @@ -181,9 +181,9 @@ func (p *Plugin) ansibleCommand(inventory string) *execabs.Cmd { ) } - if p.settings.SyntaxCheck { + if p.Settings.SyntaxCheck { args = append(args, "--syntax-check") - args = append(args, p.settings.Playbooks.Value()...) + args = append(args, p.Settings.Playbooks.Value()...) return execabs.Command( ansiblePlaybookBin, @@ -191,99 +191,99 @@ func (p *Plugin) ansibleCommand(inventory string) *execabs.Cmd { ) } - if p.settings.Check { + if p.Settings.Check { args = append(args, "--check") } - if p.settings.Diff { + if p.Settings.Diff { args = append(args, "--diff") } - if p.settings.FlushCache { + if p.Settings.FlushCache { args = append(args, "--flush-cache") } - if p.settings.ForceHandlers { + if p.Settings.ForceHandlers { args = append(args, "--force-handlers") } - if p.settings.Forks != AnsibleForksDefault { - args = append(args, "--forks", strconv.Itoa(p.settings.Forks)) + if p.Settings.Forks != AnsibleForksDefault { + args = append(args, "--forks", strconv.Itoa(p.Settings.Forks)) } - if p.settings.Limit != "" { - args = append(args, "--limit", p.settings.Limit) + if p.Settings.Limit != "" { + args = append(args, "--limit", p.Settings.Limit) } - if p.settings.ListTags { + if p.Settings.ListTags { args = append(args, "--list-tags") } - if p.settings.ListTasks { + if p.Settings.ListTasks { args = append(args, "--list-tasks") } - if p.settings.SkipTags != "" { - args = append(args, "--skip-tags", p.settings.SkipTags) + if p.Settings.SkipTags != "" { + args = append(args, "--skip-tags", p.Settings.SkipTags) } - if p.settings.StartAtTask != "" { - args = append(args, "--start-at-task", p.settings.StartAtTask) + if p.Settings.StartAtTask != "" { + args = append(args, "--start-at-task", p.Settings.StartAtTask) } - if p.settings.Tags != "" { - args = append(args, "--tags", p.settings.Tags) + if p.Settings.Tags != "" { + args = append(args, "--tags", p.Settings.Tags) } - if p.settings.PrivateKeyFile != "" { - args = append(args, "--private-key", p.settings.PrivateKeyFile) + if p.Settings.PrivateKeyFile != "" { + args = append(args, "--private-key", p.Settings.PrivateKeyFile) } - if p.settings.User != "" { - args = append(args, "--user", p.settings.User) + if p.Settings.User != "" { + args = append(args, "--user", p.Settings.User) } - if p.settings.Connection != "" { - args = append(args, "--connection", p.settings.Connection) + if p.Settings.Connection != "" { + args = append(args, "--connection", p.Settings.Connection) } - if p.settings.Timeout != 0 { - args = append(args, "--timeout", strconv.Itoa(p.settings.Timeout)) + if p.Settings.Timeout != 0 { + args = append(args, "--timeout", strconv.Itoa(p.Settings.Timeout)) } - if p.settings.SSHCommonArgs != "" { - args = append(args, "--ssh-common-args", p.settings.SSHCommonArgs) + if p.Settings.SSHCommonArgs != "" { + args = append(args, "--ssh-common-args", p.Settings.SSHCommonArgs) } - if p.settings.SFTPExtraArgs != "" { - args = append(args, "--sftp-extra-args", p.settings.SFTPExtraArgs) + if p.Settings.SFTPExtraArgs != "" { + args = append(args, "--sftp-extra-args", p.Settings.SFTPExtraArgs) } - if p.settings.SCPExtraArgs != "" { - args = append(args, "--scp-extra-args", p.settings.SCPExtraArgs) + if p.Settings.SCPExtraArgs != "" { + args = append(args, "--scp-extra-args", p.Settings.SCPExtraArgs) } - if p.settings.SSHExtraArgs != "" { - args = append(args, "--ssh-extra-args", p.settings.SSHExtraArgs) + if p.Settings.SSHExtraArgs != "" { + args = append(args, "--ssh-extra-args", p.Settings.SSHExtraArgs) } - if p.settings.Become { + if p.Settings.Become { args = append(args, "--become") } - if p.settings.BecomeMethod != "" { - args = append(args, "--become-method", p.settings.BecomeMethod) + if p.Settings.BecomeMethod != "" { + args = append(args, "--become-method", p.Settings.BecomeMethod) } - if p.settings.BecomeUser != "" { - args = append(args, "--become-user", p.settings.BecomeUser) + if p.Settings.BecomeUser != "" { + args = append(args, "--become-user", p.Settings.BecomeUser) } - if p.settings.Verbose > 0 { - args = append(args, fmt.Sprintf("-%s", strings.Repeat("v", p.settings.Verbose))) + if p.Settings.Verbose > 0 { + args = append(args, fmt.Sprintf("-%s", strings.Repeat("v", p.Settings.Verbose))) } - args = append(args, p.settings.Playbooks.Value()...) + args = append(args, p.Settings.Playbooks.Value()...) return execabs.Command( ansiblePlaybookBin, diff --git a/plugin/impl.go b/plugin/impl.go index 95d7daa..ef8558b 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -1,64 +1,39 @@ package plugin import ( + "context" "errors" + "fmt" "os" - "github.com/urfave/cli/v2" "golang.org/x/sys/execabs" ) -// Settings for the Plugin. -type Settings struct { - Requirements string - Galaxy string - Inventories cli.StringSlice - Playbooks cli.StringSlice - Limit string - SkipTags string - StartAtTask string - Tags string - ExtraVars cli.StringSlice - ModulePath cli.StringSlice - Check bool - Diff bool - FlushCache bool - ForceHandlers bool - ListHosts bool - ListTags bool - ListTasks bool - SyntaxCheck bool - Forks int - VaultID string - VaultPassword string - VaultPasswordFile string - Verbose int - PrivateKey string - PrivateKeyFile string - User string - Connection string - Timeout int - SSHCommonArgs string - SFTPExtraArgs string - SCPExtraArgs string - SSHExtraArgs string - Become bool - BecomeMethod string - BecomeUser string -} - var ( ErrPluginPlaybookNotSet = errors.New("playbook is required") ErrPluginInventoryNotSet = errors.New("inventory is required") ) +//nolint:revive +func (p *Plugin) run(ctx context.Context) error { + if err := p.Validate(); err != nil { + return fmt.Errorf("validation failed: %w", err) + } + + if err := p.Execute(); err != nil { + return fmt.Errorf("execution failed: %w", err) + } + + return nil +} + // Validate handles the settings validation of the plugin. func (p *Plugin) Validate() error { - if len(p.settings.Playbooks.Value()) == 0 { + if len(p.Settings.Playbooks.Value()) == 0 { return ErrPluginPlaybookNotSet } - if len(p.settings.Inventories.Value()) == 0 { + if len(p.Settings.Inventories.Value()) == 0 { return ErrPluginInventoryNotSet } @@ -75,35 +50,35 @@ func (p *Plugin) Execute() error { return err } - if p.settings.PrivateKey != "" { + if p.Settings.PrivateKey != "" { if err := p.privateKey(); err != nil { return err } - defer os.Remove(p.settings.PrivateKeyFile) + defer os.Remove(p.Settings.PrivateKeyFile) } - if p.settings.VaultPassword != "" { + if p.Settings.VaultPassword != "" { if err := p.vaultPass(); err != nil { return err } - defer os.Remove(p.settings.VaultPasswordFile) + defer os.Remove(p.Settings.VaultPasswordFile) } commands := []*execabs.Cmd{ p.versionCommand(), } - if p.settings.Requirements != "" { + if p.Settings.Requirements != "" { commands = append(commands, p.requirementsCommand()) } - if p.settings.Galaxy != "" { + if p.Settings.Galaxy != "" { commands = append(commands, p.galaxyCommand()) } - for _, inventory := range p.settings.Inventories.Value() { + for _, inventory := range p.Settings.Inventories.Value() { commands = append(commands, p.ansibleCommand(inventory)) } diff --git a/plugin/plugin.go b/plugin/plugin.go index eb447d9..b47534b 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,21 +1,64 @@ package plugin import ( - "github.com/drone-plugins/drone-plugin-lib/drone" + wp "github.com/thegeeklab/wp-plugin-go/plugin" + "github.com/urfave/cli/v2" ) -// Plugin implements drone.Plugin to provide the plugin implementation. +// Plugin implements provide the plugin. type Plugin struct { - settings Settings - pipeline drone.Pipeline - network drone.Network + *wp.Plugin + Settings *Settings } -// New initializes a plugin from the given Settings, Pipeline, and Network. -func New(settings Settings, pipeline drone.Pipeline, network drone.Network) *Plugin { - return &Plugin{ - settings: settings, - pipeline: pipeline, - network: network, - } +// Settings for the Plugin. +type Settings struct { + Requirements string + Galaxy string + Inventories cli.StringSlice + Playbooks cli.StringSlice + Limit string + SkipTags string + StartAtTask string + Tags string + ExtraVars cli.StringSlice + ModulePath cli.StringSlice + Check bool + Diff bool + FlushCache bool + ForceHandlers bool + ListHosts bool + ListTags bool + ListTasks bool + SyntaxCheck bool + Forks int + VaultID string + VaultPassword string + VaultPasswordFile string + Verbose int + PrivateKey string + PrivateKeyFile string + User string + Connection string + Timeout int + SSHCommonArgs string + SFTPExtraArgs string + SCPExtraArgs string + SSHExtraArgs string + Become bool + BecomeMethod string + BecomeUser string +} + +func New(options wp.Options, settings *Settings) *Plugin { + p := &Plugin{} + + if options.Execute == nil { + options.Execute = p.run + } + + p.Plugin = wp.New(options) + p.Settings = settings + + return p } diff --git a/.renovaterc.json b/renovate.json similarity index 53% rename from .renovaterc.json rename to renovate.json index 30730ef..45d1c03 100644 --- a/.renovaterc.json +++ b/renovate.json @@ -1,4 +1,4 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["github>owncloud-ci/renovate-presets:golang"] + "extends": ["github>thegeeklab/renovate-presets:golang"] }