fix linting and updating maintenance guide

Updating the maintainers guide with updated intructions from
Ansible engineers.

Fixing linting issues, and adding the linter as a GitHub workflow
to ensure there are no regressions.
This commit is contained in:
Yusuke Tsutsumi 2022-12-06 22:06:02 -08:00 committed by Yusuke Tsutsumi
parent 3fb4763e37
commit a9545c77a4
15 changed files with 91 additions and 74 deletions

View file

@ -1,34 +1,35 @@
name: "Run tests for the cloud.google collection"
on: [pull_request]
env:
PYTHON_VERSION: "3.9" # minimum version for Ansible 2.14
jobs:
# sanity tests cannot be turned on until #498 is resolved.
# sanity:
# runs-on: ubuntu-latest
# defaults:
# run:
# working-directory: ansible_collections/google/cloud
# strategy:
# matrix:
# ansible_version:
# - stable-2.13
# - stable-2.11
# steps:
# - name: check out code
# uses: actions/checkout@v2
# with:
# path: ansible_collections/google/cloud
# - name: Set up Python
# uses: actions/setup-python@v1
# with:
# python-version: '3.8' # this is the minimum version required for Ansible 2.11
# - name: Install ansible-base (${{ matrix.ansible_version }})
# uses: nick-invision/retry@v2
# with:
# timeout_minutes: 3
# max_attempts: 3
# command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
# - name: Run sanity tests
# run: ansible-test sanity --docker -v --color --python 3.8
sanity:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ansible_collections/google/cloud
strategy:
matrix:
ansible_version:
- stable-2.14
steps:
- name: check out code
uses: actions/checkout@v2
with:
path: ansible_collections/google/cloud
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install ansible-base (${{ matrix.ansible_version }})
uses: nick-invision/retry@v2
with:
timeout_minutes: 3
max_attempts: 3
command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
- name: Run sanity tests
# validate-modules cannot be turned on until #498 is resolved.
run: ansible-test sanity -v --color --python "$PYTHON_VERSION" --skip validate-modules
unit:
runs-on: ubuntu-latest
defaults:
@ -47,7 +48,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.9' # this is the minimum version required for Ansible 2.14
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: pip install -r requirements.txt
- name: Install test dependencies
@ -55,4 +56,4 @@ jobs:
- name: Install ansible-base (${{ matrix.ansible_version }})
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
- name: Run unit tests
run: ansible-test units -v --color --python 3.9
run: ansible-test units -v --color --python "$PYTHON_VERSION"

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ tests/integration/cloud-config-gcp.ini
tests/integration/inventory
tests/output/
__pycache__
*.tar.gz

View file

@ -58,11 +58,23 @@ antsibull-changelog release
This will remove all the changelog fragments from ./changelogs/fragments and
merge them into CHANGELOG.rst.
### Tag a release
### Create a new GitHub release
The release process is mostly automated, relying on GitHub releases and the following
workflows:
Creating
- [publish to Ansible Galaxy](./.github/workflows/pythonpublish.yml).
- [publish to Automation Hub](./.github/workflows/automationhub.yml).
### Publish to Automation Hub
*note*: As automation Hub only accepts production releases, this step
is only required for new full releases.
This step does not use GitHub actions, as API keys for Automation Hub
expire after 30 days of no use, and a maintainer may find themselves
refreshing tokens every time anyway.
Steps:
1. Build the package locally: `ansible-galaxy collection build .`
1. [Go to the Automation Hub my-namespaces page, then click on Google](https://console.redhat.com/ansible/automation-hub/repo/published/my-namespaces/google/)
1. Publish the package

View file

@ -521,7 +521,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
return self._return_if_object(module, response)
def projects_for_folder(self, config_data, folder):
link = 'https://cloudresourcemanager.googleapis.com/v1/projects'.format()
link = 'https://cloudresourcemanager.googleapis.com/v1/projects'
query = 'parent.id = {0}'.format(folder)
projects = []
config_data['scopes'] = ['https://www.googleapis.com/auth/cloud-platform']

View file

@ -1433,7 +1433,7 @@ def main():
elements="dict",
options=dict(
balancing_mode=dict(default="UTILIZATION", type="str"),
# TODO: capacity_scaler does some value normalization
# TODO: capacity_scaler does some value normalization
# server-side, so there needs to be a way to do proper
# value comparison.
capacity_scaler=dict(default="1", type="str"),

View file

@ -961,7 +961,7 @@ options:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the
only place a \* is allowed is at the end following a /. The string fed
only place a \\ * is allowed is at the end following a /. The string fed
to the path matcher does not include any text after the first ? or #,
and those chars are not allowed here.'
elements: str
@ -2522,7 +2522,7 @@ pathMatchers:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the only
place a \* is allowed is at the end following a /. The string fed to the
place a \\* is allowed is at the end following a /. The string fed to the
path matcher does not include any text after the first ? or #, and those
chars are not allowed here.'
returned: success

View file

@ -991,7 +991,7 @@ resources:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the
only place a \* is allowed is at the end following a /. The string
only place a \\* is allowed is at the end following a /. The string
fed to the path matcher does not include any text after the first
? or #, and those chars are not allowed here.'
returned: success

View file

@ -325,7 +325,7 @@ options:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the
only place a \* is allowed is at the end following a /. The string fed
only place a \\* is allowed is at the end following a /. The string fed
to the path matcher does not include any text after the first ? or #,
and those chars are not allowed here.'
elements: str
@ -2899,7 +2899,7 @@ pathMatchers:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the only
place a \* is allowed is at the end following a /. The string fed to the
place a \\* is allowed is at the end following a /. The string fed to the
path matcher does not include any text after the first ? or #, and those
chars are not allowed here.'
returned: success
@ -5489,10 +5489,10 @@ def main():
if fetch:
module.params['fingerprint'] = fetch['fingerprint']
if state == 'present':
if is_different(module, fetch):
update(module, self_link(module), kind)
fetch = fetch_resource(module, self_link(module), kind)
changed = True
if is_different(module, fetch):
update(module, self_link(module), kind)
fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
fetch = {}

View file

@ -382,7 +382,7 @@ resources:
paths:
description:
- 'The list of path patterns to match. Each must start with / and the
only place a \* is allowed is at the end following a /. The string
only place a \\* is allowed is at the end following a /. The string
fed to the path matcher does not include any text after the first
? or #, and those chars are not allowed here.'
returned: success

View file

@ -535,14 +535,14 @@ def is_different(module, response):
response_vals = {}
for k, v in response.items():
if k in keys_to_ignore:
continue
continue
if k in request:
response_vals[k] = v
request_vals = {}
for k, v in request.items():
if k in keys_to_ignore:
continue
continue
if k in response:
request_vals[k] = v

View file

@ -219,9 +219,9 @@ def main():
fetch = fetch_resource(module, self_link(module))
changed = True
elif not fetch.get("deleted"):
delete(module, self_link(module))
fetch = {}
changed = True
delete(module, self_link(module))
fetch = {}
changed = True
else:
if state == "present":
fetch = create(module, collection(module))
@ -242,7 +242,7 @@ def create(module, link):
def undelete(module, link, etag):
auth = GcpSession(module, "iam")
return return_if_object(module, auth.post(link + ":undelete", {
"etag": etag
"etag": etag
}))
@ -322,8 +322,8 @@ def return_if_object(module, response, allow_not_found=False):
# catches and edge case specific to IAM roles where the role not
# existing returns 400.
if (allow_not_found and response.status_code == 400
and "You can't delete role_id" in response.text):
if (allow_not_found and response.status_code == 400
and "You can't delete role_id" in response.text):
return None
try:

@ -1 +0,0 @@
Subproject commit 9a36582f0d762e386a56e698d896c22bebf6d904

View file

@ -8,42 +8,45 @@
# - google-cloud-sdk (gcloudgcloud )
set -e
PROJECT_ID="${1}"
SERVICE_ACCOUNT_NAME="${2}"
# service account is unused today
# SERVICE_ACCOUNT_NAME="${2}"
ZONE="us-central1-a"
main() {
# note: the ordering here is deliberate, to start with
# leaf resources and work upwards to parent resources.
cleanup_resource_per_region "compute vpn-tunnels"
cleanup_resource "compute instances" "" "--zone=$ZONE"
cleanup_resource_per_region "compute addresses"
cleanup_resource "compute target-http-proxies" "" "--global"
cleanup_resource "compute forwarding-rules" "--global" "--global"
cleanup_resource "compute forwarding-rules" \
cleanup_resource_per_region "compute" "vpn-tunnels"
cleanup_resource "compute" "instances" "" "--zone=$ZONE"
cleanup_resource_per_region "compute" "addresses"
cleanup_resource "compute" "target-http-proxies" "" "--global"
cleanup_resource "compute" "forwarding-rules" "--global" "--global"
cleanup_resource "compute" "forwarding-rules" \
"--regions=us-central1" "--region=us-central1"
cleanup_resource "compute url-maps" "--global" "--global"
cleanup_resource "compute url-maps" \
cleanup_resource "compute" "url-maps" "--global" "--global"
cleanup_resource "compute" "url-maps" \
"--regions=us-central1" "--region=us-central1"
cleanup_resource "compute backend-services" "--global" "--global"
cleanup_resource "compute backend-services" \
cleanup_resource "compute" "backend-services" "--global" "--global"
cleanup_resource "compute" "backend-services" \
"--regions=us-central1" "--region=us-central1"
}
cleanup_resource() {
resource_group="$1"
extra_list_args="$2"
extra_delete_args="$3"
resource="$2"
extra_list_arg="$3"
extra_delete_arg="$4"
for resource in $(gcloud $resource_group list --project="${PROJECT_ID}" --format="csv[no-heading](name)" $extra_list_args); do
gcloud $resource_group delete "${resource}" --project="${PROJECT_ID}" -q $extra_delete_args
for resource_id in $(gcloud "${resource_group}" "${resource}" list --project="${PROJECT_ID}" --format="csv[no-heading](name)" "${extra_list_arg}"); do
gcloud "${resource_group}" "${resource}" delete "${resource_id}" --project="${PROJECT_ID}" -q "${extra_delete_arg}"
done
}
cleanup_resource_per_region() {
resource_group="$1"
for resource_and_region in $(gcloud $resource_group list --project="${PROJECT_ID}" --format="csv[no-heading](name,region)"); do
read -r resource region < <(echo "$resource_and_region" | tr "," " ")
gcloud $resource_group delete "${resource}" --project="${PROJECT_ID}" -q --region="${region}"
resource="$2"
for resource_and_region in $(gcloud "${resource_group}" "${resource}" list --project="${PROJECT_ID}" --format="csv[no-heading](name,region)"); do
read -r resource_id region < <(echo "$resource_and_region" | tr "," " ")
gcloud "${resource_group}" "${resource}" delete "${resource_id}" --project="${PROJECT_ID}" -q --region="${region}"
done
}

View file

@ -4,4 +4,4 @@
if [ -f ../cloud-function.zip ]; then
rm ../cloud-function.zip
fi
zip ../cloud-function.zip *
zip ../cloud-function.zip ./*

View file

@ -1,5 +1,6 @@
import functions_framework
# Register an HTTP function with the Functions Framework
@functions_framework.http
def helloGET(request):