mirror of
https://github.com/ansible-collections/google.cloud.git
synced 2025-08-25 07:21:49 -07:00
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:
parent
3fb4763e37
commit
a9545c77a4
15 changed files with 91 additions and 74 deletions
61
.github/workflows/ansible-test.yml
vendored
61
.github/workflows/ansible-test.yml
vendored
|
@ -1,34 +1,35 @@
|
||||||
name: "Run tests for the cloud.google collection"
|
name: "Run tests for the cloud.google collection"
|
||||||
on: [pull_request]
|
on: [pull_request]
|
||||||
|
env:
|
||||||
|
PYTHON_VERSION: "3.9" # minimum version for Ansible 2.14
|
||||||
jobs:
|
jobs:
|
||||||
# sanity tests cannot be turned on until #498 is resolved.
|
sanity:
|
||||||
# sanity:
|
runs-on: ubuntu-latest
|
||||||
# runs-on: ubuntu-latest
|
defaults:
|
||||||
# defaults:
|
run:
|
||||||
# run:
|
working-directory: ansible_collections/google/cloud
|
||||||
# working-directory: ansible_collections/google/cloud
|
strategy:
|
||||||
# strategy:
|
matrix:
|
||||||
# matrix:
|
ansible_version:
|
||||||
# ansible_version:
|
- stable-2.14
|
||||||
# - stable-2.13
|
steps:
|
||||||
# - stable-2.11
|
- name: check out code
|
||||||
# steps:
|
uses: actions/checkout@v2
|
||||||
# - name: check out code
|
with:
|
||||||
# uses: actions/checkout@v2
|
path: ansible_collections/google/cloud
|
||||||
# with:
|
- name: Set up Python
|
||||||
# path: ansible_collections/google/cloud
|
uses: actions/setup-python@v1
|
||||||
# - name: Set up Python
|
with:
|
||||||
# uses: actions/setup-python@v1
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
# with:
|
- name: Install ansible-base (${{ matrix.ansible_version }})
|
||||||
# python-version: '3.8' # this is the minimum version required for Ansible 2.11
|
uses: nick-invision/retry@v2
|
||||||
# - name: Install ansible-base (${{ matrix.ansible_version }})
|
with:
|
||||||
# uses: nick-invision/retry@v2
|
timeout_minutes: 3
|
||||||
# with:
|
max_attempts: 3
|
||||||
# timeout_minutes: 3
|
command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
|
||||||
# max_attempts: 3
|
- name: Run sanity tests
|
||||||
# command: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
|
# validate-modules cannot be turned on until #498 is resolved.
|
||||||
# - name: Run sanity tests
|
run: ansible-test sanity -v --color --python "$PYTHON_VERSION" --skip validate-modules
|
||||||
# run: ansible-test sanity --docker -v --color --python 3.8
|
|
||||||
unit:
|
unit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
defaults:
|
defaults:
|
||||||
|
@ -47,7 +48,7 @@ jobs:
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: '3.9' # this is the minimum version required for Ansible 2.14
|
python-version: ${{ env.PYTHON_VERSION }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
- name: Install test dependencies
|
- name: Install test dependencies
|
||||||
|
@ -55,4 +56,4 @@ jobs:
|
||||||
- name: Install ansible-base (${{ matrix.ansible_version }})
|
- 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
|
run: pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible_version }}.tar.gz --disable-pip-version-check
|
||||||
- name: Run unit tests
|
- 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
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ tests/integration/cloud-config-gcp.ini
|
||||||
tests/integration/inventory
|
tests/integration/inventory
|
||||||
tests/output/
|
tests/output/
|
||||||
__pycache__
|
__pycache__
|
||||||
|
*.tar.gz
|
||||||
|
|
|
@ -58,11 +58,23 @@ antsibull-changelog release
|
||||||
This will remove all the changelog fragments from ./changelogs/fragments and
|
This will remove all the changelog fragments from ./changelogs/fragments and
|
||||||
merge them into CHANGELOG.rst.
|
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
|
Creating
|
||||||
workflows:
|
|
||||||
|
|
||||||
- [publish to Ansible Galaxy](./.github/workflows/pythonpublish.yml).
|
- [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
|
|
@ -521,7 +521,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
return self._return_if_object(module, response)
|
return self._return_if_object(module, response)
|
||||||
|
|
||||||
def projects_for_folder(self, config_data, folder):
|
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)
|
query = 'parent.id = {0}'.format(folder)
|
||||||
projects = []
|
projects = []
|
||||||
config_data['scopes'] = ['https://www.googleapis.com/auth/cloud-platform']
|
config_data['scopes'] = ['https://www.googleapis.com/auth/cloud-platform']
|
||||||
|
|
|
@ -1433,7 +1433,7 @@ def main():
|
||||||
elements="dict",
|
elements="dict",
|
||||||
options=dict(
|
options=dict(
|
||||||
balancing_mode=dict(default="UTILIZATION", type="str"),
|
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
|
# server-side, so there needs to be a way to do proper
|
||||||
# value comparison.
|
# value comparison.
|
||||||
capacity_scaler=dict(default="1", type="str"),
|
capacity_scaler=dict(default="1", type="str"),
|
||||||
|
|
|
@ -961,7 +961,7 @@ options:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the
|
- '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 #,
|
to the path matcher does not include any text after the first ? or #,
|
||||||
and those chars are not allowed here.'
|
and those chars are not allowed here.'
|
||||||
elements: str
|
elements: str
|
||||||
|
@ -2522,7 +2522,7 @@ pathMatchers:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the only
|
- '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
|
path matcher does not include any text after the first ? or #, and those
|
||||||
chars are not allowed here.'
|
chars are not allowed here.'
|
||||||
returned: success
|
returned: success
|
||||||
|
|
|
@ -991,7 +991,7 @@ resources:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the
|
- '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
|
fed to the path matcher does not include any text after the first
|
||||||
? or #, and those chars are not allowed here.'
|
? or #, and those chars are not allowed here.'
|
||||||
returned: success
|
returned: success
|
||||||
|
|
|
@ -325,7 +325,7 @@ options:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the
|
- '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 #,
|
to the path matcher does not include any text after the first ? or #,
|
||||||
and those chars are not allowed here.'
|
and those chars are not allowed here.'
|
||||||
elements: str
|
elements: str
|
||||||
|
@ -2899,7 +2899,7 @@ pathMatchers:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the only
|
- '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
|
path matcher does not include any text after the first ? or #, and those
|
||||||
chars are not allowed here.'
|
chars are not allowed here.'
|
||||||
returned: success
|
returned: success
|
||||||
|
@ -5489,10 +5489,10 @@ def main():
|
||||||
if fetch:
|
if fetch:
|
||||||
module.params['fingerprint'] = fetch['fingerprint']
|
module.params['fingerprint'] = fetch['fingerprint']
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
if is_different(module, fetch):
|
if is_different(module, fetch):
|
||||||
update(module, self_link(module), kind)
|
update(module, self_link(module), kind)
|
||||||
fetch = fetch_resource(module, self_link(module), kind)
|
fetch = fetch_resource(module, self_link(module), kind)
|
||||||
changed = True
|
changed = True
|
||||||
else:
|
else:
|
||||||
delete(module, self_link(module), kind)
|
delete(module, self_link(module), kind)
|
||||||
fetch = {}
|
fetch = {}
|
||||||
|
|
|
@ -382,7 +382,7 @@ resources:
|
||||||
paths:
|
paths:
|
||||||
description:
|
description:
|
||||||
- 'The list of path patterns to match. Each must start with / and the
|
- '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
|
fed to the path matcher does not include any text after the first
|
||||||
? or #, and those chars are not allowed here.'
|
? or #, and those chars are not allowed here.'
|
||||||
returned: success
|
returned: success
|
||||||
|
|
|
@ -535,14 +535,14 @@ def is_different(module, response):
|
||||||
response_vals = {}
|
response_vals = {}
|
||||||
for k, v in response.items():
|
for k, v in response.items():
|
||||||
if k in keys_to_ignore:
|
if k in keys_to_ignore:
|
||||||
continue
|
continue
|
||||||
if k in request:
|
if k in request:
|
||||||
response_vals[k] = v
|
response_vals[k] = v
|
||||||
|
|
||||||
request_vals = {}
|
request_vals = {}
|
||||||
for k, v in request.items():
|
for k, v in request.items():
|
||||||
if k in keys_to_ignore:
|
if k in keys_to_ignore:
|
||||||
continue
|
continue
|
||||||
if k in response:
|
if k in response:
|
||||||
request_vals[k] = v
|
request_vals[k] = v
|
||||||
|
|
||||||
|
|
|
@ -219,9 +219,9 @@ def main():
|
||||||
fetch = fetch_resource(module, self_link(module))
|
fetch = fetch_resource(module, self_link(module))
|
||||||
changed = True
|
changed = True
|
||||||
elif not fetch.get("deleted"):
|
elif not fetch.get("deleted"):
|
||||||
delete(module, self_link(module))
|
delete(module, self_link(module))
|
||||||
fetch = {}
|
fetch = {}
|
||||||
changed = True
|
changed = True
|
||||||
else:
|
else:
|
||||||
if state == "present":
|
if state == "present":
|
||||||
fetch = create(module, collection(module))
|
fetch = create(module, collection(module))
|
||||||
|
@ -242,7 +242,7 @@ def create(module, link):
|
||||||
def undelete(module, link, etag):
|
def undelete(module, link, etag):
|
||||||
auth = GcpSession(module, "iam")
|
auth = GcpSession(module, "iam")
|
||||||
return return_if_object(module, auth.post(link + ":undelete", {
|
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
|
# catches and edge case specific to IAM roles where the role not
|
||||||
# existing returns 400.
|
# existing returns 400.
|
||||||
if (allow_not_found and response.status_code == 400
|
if (allow_not_found and response.status_code == 400
|
||||||
and "You can't delete role_id" in response.text):
|
and "You can't delete role_id" in response.text):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 9a36582f0d762e386a56e698d896c22bebf6d904
|
|
|
@ -8,42 +8,45 @@
|
||||||
# - google-cloud-sdk (gcloudgcloud )
|
# - google-cloud-sdk (gcloudgcloud )
|
||||||
set -e
|
set -e
|
||||||
PROJECT_ID="${1}"
|
PROJECT_ID="${1}"
|
||||||
SERVICE_ACCOUNT_NAME="${2}"
|
# service account is unused today
|
||||||
|
# SERVICE_ACCOUNT_NAME="${2}"
|
||||||
ZONE="us-central1-a"
|
ZONE="us-central1-a"
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
# note: the ordering here is deliberate, to start with
|
# note: the ordering here is deliberate, to start with
|
||||||
# leaf resources and work upwards to parent resources.
|
# leaf resources and work upwards to parent resources.
|
||||||
cleanup_resource_per_region "compute vpn-tunnels"
|
cleanup_resource_per_region "compute" "vpn-tunnels"
|
||||||
cleanup_resource "compute instances" "" "--zone=$ZONE"
|
cleanup_resource "compute" "instances" "" "--zone=$ZONE"
|
||||||
cleanup_resource_per_region "compute addresses"
|
cleanup_resource_per_region "compute" "addresses"
|
||||||
cleanup_resource "compute target-http-proxies" "" "--global"
|
cleanup_resource "compute" "target-http-proxies" "" "--global"
|
||||||
cleanup_resource "compute forwarding-rules" "--global" "--global"
|
cleanup_resource "compute" "forwarding-rules" "--global" "--global"
|
||||||
cleanup_resource "compute forwarding-rules" \
|
cleanup_resource "compute" "forwarding-rules" \
|
||||||
"--regions=us-central1" "--region=us-central1"
|
"--regions=us-central1" "--region=us-central1"
|
||||||
cleanup_resource "compute url-maps" "--global" "--global"
|
cleanup_resource "compute" "url-maps" "--global" "--global"
|
||||||
cleanup_resource "compute url-maps" \
|
cleanup_resource "compute" "url-maps" \
|
||||||
"--regions=us-central1" "--region=us-central1"
|
"--regions=us-central1" "--region=us-central1"
|
||||||
cleanup_resource "compute backend-services" "--global" "--global"
|
cleanup_resource "compute" "backend-services" "--global" "--global"
|
||||||
cleanup_resource "compute backend-services" \
|
cleanup_resource "compute" "backend-services" \
|
||||||
"--regions=us-central1" "--region=us-central1"
|
"--regions=us-central1" "--region=us-central1"
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_resource() {
|
cleanup_resource() {
|
||||||
resource_group="$1"
|
resource_group="$1"
|
||||||
extra_list_args="$2"
|
resource="$2"
|
||||||
extra_delete_args="$3"
|
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
|
for resource_id in $(gcloud "${resource_group}" "${resource}" list --project="${PROJECT_ID}" --format="csv[no-heading](name)" "${extra_list_arg}"); do
|
||||||
gcloud $resource_group delete "${resource}" --project="${PROJECT_ID}" -q $extra_delete_args
|
gcloud "${resource_group}" "${resource}" delete "${resource_id}" --project="${PROJECT_ID}" -q "${extra_delete_arg}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_resource_per_region() {
|
cleanup_resource_per_region() {
|
||||||
resource_group="$1"
|
resource_group="$1"
|
||||||
for resource_and_region in $(gcloud $resource_group list --project="${PROJECT_ID}" --format="csv[no-heading](name,region)"); do
|
resource="$2"
|
||||||
read -r resource region < <(echo "$resource_and_region" | tr "," " ")
|
for resource_and_region in $(gcloud "${resource_group}" "${resource}" list --project="${PROJECT_ID}" --format="csv[no-heading](name,region)"); do
|
||||||
gcloud $resource_group delete "${resource}" --project="${PROJECT_ID}" -q --region="${region}"
|
read -r resource_id region < <(echo "$resource_and_region" | tr "," " ")
|
||||||
|
gcloud "${resource_group}" "${resource}" delete "${resource_id}" --project="${PROJECT_ID}" -q --region="${region}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
if [ -f ../cloud-function.zip ]; then
|
if [ -f ../cloud-function.zip ]; then
|
||||||
rm ../cloud-function.zip
|
rm ../cloud-function.zip
|
||||||
fi
|
fi
|
||||||
zip ../cloud-function.zip *
|
zip ../cloud-function.zip ./*
|
|
@ -1,5 +1,6 @@
|
||||||
import functions_framework
|
import functions_framework
|
||||||
|
|
||||||
|
|
||||||
# Register an HTTP function with the Functions Framework
|
# Register an HTTP function with the Functions Framework
|
||||||
@functions_framework.http
|
@functions_framework.http
|
||||||
def helloGET(request):
|
def helloGET(request):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue