diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 3fb63354..49fbfb0b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -196,59 +196,30 @@ jobs: - name: Notify Slack uses: slackapi/slack-github-action@v2.0.0 with: - channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} payload: | - { - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:" - } - }, - { - "type": "divider" - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Build Result:*\n${{ needs.integration-tests.result == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" - }, - { - "type": "mrkdwn", - "text": "*Branch:*\n`${{ github.ref_name }}`" - } - ] - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>" - }, - { - "type": "mrkdwn", - "text": "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>" - } - ] - }, - { - "type": "divider" - }, - { - "type": "context", - "elements": [ - { - "type": "mrkdwn", - "text": "Triggered by: :bust_in_silhouette: `${{ github.actor }}`" - } - ] - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} \ No newline at end of file + channel: ${{ secrets.SLACK_CHANNEL_ID }} + blocks: + - type: section + text: + type: mrkdwn + text: ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:" + - type: divider + - type: section + fields: + - type: mrkdwn + text: "*Build Result:*\n${{ needs.integration-tests.result == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" + - type: mrkdwn + text: "*Branch:*\n`${{ github.ref_name }}`" + - type: section + fields: + - type: mrkdwn + text: "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>" + - type: mrkdwn + text: "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>" + - type: divider + - type: context + elements: + - type: mrkdwn + text: "Triggered by: :bust_in_silhouette: `${{ github.actor }}`" \ No newline at end of file diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml index 99b669c2..d3f53cd0 100644 --- a/.github/workflows/release-notify-slack.yml +++ b/.github/workflows/release-notify-slack.yml @@ -13,30 +13,12 @@ jobs: id: main_message uses: slackapi/slack-github-action@v2.0.0 with: - channel-id: ${{ secrets.DEV_DX_SLACK_CHANNEL_ID }} + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} payload: | - { - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "*New Release Published: _ansible_linode_ - ${{ github.event.release.tag_name }} is now live!* :tada:" - } - } - ] - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - - - name: Notify Slack - Threaded Release Notes - uses: slackapi/slack-github-action@v2.0.0 - with: - channel-id: ${{ secrets.DEV_DX_SLACK_CHANNEL_ID }} - payload: | - { - "thread_ts": "${{ steps.main_message.outputs.ts }}", - "text": "*<${{ github.event.release.html_url }}| ${{ github.event.release.tag_name }} Release notes>*" - } - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + channel: ${{ secrets.DEV_DX_SLACK_CHANNEL_ID }} + blocks: + - type: section + text: + type: mrkdwn + text: "*New Release Published: _ansible_linode_ <${{ github.event.release.html_url }}|${{ github.event.release.tag_name }}> is now live!* :tada:" diff --git a/Makefile b/Makefile index a5d6dcf2..60e3a4c3 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ install: build ansible-galaxy collection install *.tar.gz --force -p $(COLLECTIONS_PATH) deps: - pip install -r requirements.txt -r requirements-dev.txt --upgrade + pip install -r requirements.txt -r requirements-dev.txt --force lint: pylint plugins diff --git a/plugins/module_utils/linode_common.py b/plugins/module_utils/linode_common.py index b05dfc95..d5f35f3a 100644 --- a/plugins/module_utils/linode_common.py +++ b/plugins/module_utils/linode_common.py @@ -7,7 +7,6 @@ import polling from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import ( - format_api_error, format_generic_error, ) @@ -159,7 +158,7 @@ def __init__( res = self.exec_module(**self.module.params) except ApiError as err: # We don't want to return a stack trace for an API error - self.fail(msg=format_api_error(err)) + self.fail(msg=f"Error from Linode API: {str(err)}") except polling.TimeoutException as err: self.fail( msg="failed to wait for condition: timeout period expired" diff --git a/plugins/module_utils/linode_helper.py b/plugins/module_utils/linode_helper.py index f2d69ed4..0429881b 100644 --- a/plugins/module_utils/linode_helper.py +++ b/plugins/module_utils/linode_helper.py @@ -5,7 +5,6 @@ import linode_api4 import polling from linode_api4 import ( - ApiError, LinodeClient, LKENodePool, LKENodePoolNode, @@ -329,12 +328,6 @@ def get_all_paginated( return result -def format_api_error(err: ApiError) -> str: - """Formats an API error into a readable string""" - - return f"Error from Linode API: [{err.status}] {';'.join(err.errors)}" - - def format_generic_error(err: Exception) -> str: """Formats a generic error into a readable string""" diff --git a/requirements.txt b/requirements.txt index d1030e00..3490bb5b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -linode-api4>=5.22.0 +linode-api4>=5.24.0 polling==0.3.2 ansible-specdoc>=0.0.15 diff --git a/tests/integration/targets/api_error/tasks/main.yaml b/tests/integration/targets/api_error/tasks/main.yaml new file mode 100644 index 00000000..afeb74b7 --- /dev/null +++ b/tests/integration/targets/api_error/tasks/main.yaml @@ -0,0 +1,24 @@ +- name: api_error + block: + - name: Attempt to create an instance with validation errors + linode.cloud.instance: + region: fake-region + type: g6-fake-plan + state: present + register: failing_request + failed_when: '"msg" not in failing_request' + + - name: Ensure the error message is formatted as expected + assert: + that: + - failing_request.changed == False + - 'failing_request.msg.startswith("Error from Linode API: POST /v4beta/linode/instances: [400]")' + - '"type: A valid plan type by that ID was not found" in failing_request.msg' + - '"region: region is not valid" in failing_request.msg' + + environment: + LINODE_UA_PREFIX: '{{ ua_prefix }}' + LINODE_API_TOKEN: '{{ api_token }}' + LINODE_API_URL: '{{ api_url }}' + LINODE_API_VERSION: '{{ api_version }}' + LINODE_CA: '{{ ca_file or "" }}'