diff --git a/.github/workflows/integration-tests-pr.yml b/.github/workflows/integration-tests-pr.yml index 1f90c98c..e10b9145 100644 --- a/.github/workflows/integration-tests-pr.yml +++ b/.github/workflows/integration-tests-pr.yml @@ -63,25 +63,10 @@ jobs: - name: replace existing keys run: rm -rf ~/.ansible/test && mkdir -p ~/.ansible/test && ssh-keygen -m PEM -q -t rsa -N '' -f ~/.ansible/test/id_rsa - - name: Download kubectl and calicoctl for LKE clusters - run: | - curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" - curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" - chmod +x calicoctl-linux-amd64 kubectl - mv calicoctl-linux-amd64 /usr/local/bin/calicoctl - mv kubectl /usr/local/bin/kubectl - - run: make deps && make TEST_ARGS="-v ${{ inputs.tests }}" test if: ${{ steps.disallowed-char-check.outputs.match == '' }} env: LINODE_API_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} - - - name: Apply Calico Rules to LKE - if: always() - run: | - cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh - env: - LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} - name: Get the hash value of the latest commit from the PR branch uses: octokit/graphql-action@v2.x @@ -135,3 +120,60 @@ jobs: conclusion: process.env.conclusion }); return result; + + apply-calico-rules: + runs-on: ubuntu-latest + needs: [integration-fork] + if: ${{ success() || failure() }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: 'recursive' + + - name: Download kubectl and calicoctl for LKE clusters + run: | + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" + chmod +x calicoctl-linux-amd64 kubectl + mv calicoctl-linux-amd64 /usr/local/bin/calicoctl + mv kubectl /usr/local/bin/kubectl + + - name: Apply Calico Rules to LKE + run: | + cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh + env: + LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} + + add-fw-to-remaining-instances: + runs-on: ubuntu-latest + needs: [integration-fork] + if: ${{ success() || failure() }} + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Linode CLI + run: | + pip install linode-cli + + - name: Create Firewall and Attach to Instances + run: | + FIREWALL_ID=$(linode-cli firewalls create --label "e2e-fw-$(date +%s)" --rules.inbound_policy "DROP" --rules.outbound_policy "ACCEPT" --text --format=id --no-headers) + echo "Created Firewall with ID: $FIREWALL_ID" + + for instance_id in $(linode-cli linodes list --format "id" --text --no-header); do + echo "Attaching firewall to instance: $instance_id" + if linode-cli firewalls device-create "$FIREWALL_ID" --id "$instance_id" --type linode; then + echo "Firewall attached to instance $instance_id successfully." + else + echo "An error occurred while attaching firewall to instance $instance_id. Skipping..." + fi + done + env: + LINODE_CLI_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index b508dab0..bc51094e 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -43,14 +43,6 @@ jobs: - name: Replace Existing Keys run: rm -rf ~/.ansible/test && mkdir -p ~/.ansible/test && ssh-keygen -m PEM -q -t rsa -N '' -f ~/.ansible/test/id_rsa - - name: Download kubectl and calicoctl for LKE clusters - run: | - curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" - curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" - chmod +x calicoctl-linux-amd64 kubectl - mv calicoctl-linux-amd64 /usr/local/bin/calicoctl - mv kubectl /usr/local/bin/kubectl - - name: Run Integration Tests run: | make testall @@ -58,13 +50,6 @@ jobs: LINODE_API_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} ANSIBLE_CALLBACKS_ENABLED: "junit" - - name: Apply Calico Rules to LKE - if: always() - run: | - cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh - env: - LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} - - name: Upload Test Report as Artifact if: always() uses: actions/upload-artifact@v4 @@ -78,7 +63,7 @@ jobs: process-upload-report: runs-on: ubuntu-latest needs: [integration-tests] - if: always() && github.repository == 'linode/ansible_linode' + if: ${{ (success() || failure()) && github.repository == 'linode/ansible_linode' }} steps: - name: Checkout code @@ -128,10 +113,67 @@ jobs: LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }} LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }} + apply-calico-rules: + runs-on: ubuntu-latest + needs: [integration-tests] + if: ${{ success() || failure() }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: 'recursive' + + - name: Download kubectl and calicoctl for LKE clusters + run: | + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" + chmod +x calicoctl-linux-amd64 kubectl + mv calicoctl-linux-amd64 /usr/local/bin/calicoctl + mv kubectl /usr/local/bin/kubectl + + - name: Apply Calico Rules to LKE + run: | + cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh + env: + LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} + + add-fw-to-remaining-instances: + runs-on: ubuntu-latest + needs: [integration-tests] + if: ${{ success() || failure() }} + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Linode CLI + run: | + pip install linode-cli + + - name: Create Firewall and Attach to Instances + run: | + FIREWALL_ID=$(linode-cli firewalls create --label "e2e-fw-$(date +%s)" --rules.inbound_policy "DROP" --rules.outbound_policy "ACCEPT" --text --format=id --no-headers) + echo "Created Firewall with ID: $FIREWALL_ID" + + for instance_id in $(linode-cli linodes list --format "id" --text --no-header); do + echo "Attaching firewall to instance: $instance_id" + if linode-cli firewalls device-create "$FIREWALL_ID" --id "$instance_id" --type linode; then + echo "Firewall attached to instance $instance_id successfully." + else + echo "An error occurred while attaching firewall to instance $instance_id. Skipping..." + fi + done + env: + LINODE_CLI_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} + notify-slack: runs-on: ubuntu-latest needs: [integration-tests] - if: always() && github.repository == 'linode/ansible_linode' # Run even if integration tests fail and only on main repository + if: ${{ (success() || failure()) && github.repository == 'linode/ansible_linode' }} # Run even if integration tests fail and only on main repository steps: - name: Notify Slack diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml new file mode 100644 index 00000000..59a1f252 --- /dev/null +++ b/.github/workflows/release-notify-slack.yml @@ -0,0 +1,42 @@ +name: Notify Dev DX Channel on Release +on: + release: + types: [published] + workflow_dispatch: null + +jobs: + notify: + if: github.repository == 'linode/ansible_linode' + runs-on: ubuntu-latest + steps: + - name: Notify Slack - Main Message + id: main_message + uses: slackapi/slack-github-action@v1.27.0 + with: + channel-id: ${{ secrets.DEV_DX_SLACK_CHANNEL_ID }} + 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@v1.27.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 }} diff --git a/Makefile b/Makefile index 3bcf736a..a5d6dcf2 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ deps: pip install -r requirements.txt -r requirements-dev.txt --upgrade lint: - pylint --disable=too-many-positional-arguments plugins + pylint plugins mypy plugins/modules mypy plugins/inventory diff --git a/docs/modules/instance.md b/docs/modules/instance.md index ec74812d..2ba7737b 100644 --- a/docs/modules/instance.md +++ b/docs/modules/instance.md @@ -148,6 +148,7 @@ Manage Linode Instances, Configs, and Disks. | `migration_type` |
`str`
|
Optional
| The type of migration to use for Region and Type migrations. **(Choices: `cold`, `warm`; Default: `cold`)** | | `auto_disk_resize` |
`bool`
|
Optional
| Whether implicitly created disks should be resized during a type change operation. **(Default: `False`)** | | `tags` |
`list`
|
Optional
| An array of tags applied to this object. Tags are for organizational purposes only. **(Updatable)** | +| `capabilities` |
`list`
|
Optional
| Read-only. A list of capabilities this compute instance supports. | | [`placement_group` (sub-options)](#placement_group) |
`dict`
|
Optional
| A Placement Group to create this Linode under. | | `disk_encryption` |
`str`
|
Optional
| The disk encryption status of this Linode. NOTE: Disk encryption may not currently be available to all users. **(Choices: `enabled`, `disabled`)** | | `swap_size` |
`int`
|
Optional
| When deploying from an Image, this field is optional, otherwise it is ignored. This is used to set the swap disk size for the newly-created Linode. | diff --git a/docs/modules/placement_group.md b/docs/modules/placement_group.md index e376a0f0..afd7dfa8 100644 --- a/docs/modules/placement_group.md +++ b/docs/modules/placement_group.md @@ -2,8 +2,6 @@ Manage a Linode Placement Group. -NOTE: Placement Groups may not currently be available to all users. - - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) - [Parameters](#parameters) diff --git a/docs/modules/placement_group_assign.md b/docs/modules/placement_group_assign.md index 701d3f66..cbc39511 100644 --- a/docs/modules/placement_group_assign.md +++ b/docs/modules/placement_group_assign.md @@ -2,8 +2,6 @@ Manages a single assignment between a Linode and a Placement Group. -NOTE: Placement Groups may not currently be available to all users. - - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) - [Parameters](#parameters) diff --git a/docs/modules/placement_group_info.md b/docs/modules/placement_group_info.md index 79799fa4..47bbebcc 100644 --- a/docs/modules/placement_group_info.md +++ b/docs/modules/placement_group_info.md @@ -2,8 +2,6 @@ Get info about a Linode Placement Group. -WARNING! This module makes use of beta endpoints and requires the C(api_version) field be explicitly set to C(v4beta). - - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) - [Parameters](#parameters) diff --git a/docs/modules/placement_group_list.md b/docs/modules/placement_group_list.md index 8b74e292..e2d576e1 100644 --- a/docs/modules/placement_group_list.md +++ b/docs/modules/placement_group_list.md @@ -2,8 +2,6 @@ List and filter on Placement Groups. -WARNING! This module makes use of beta endpoints and requires the C(api_version) field be explicitly set to C(v4beta). - - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) - [Parameters](#parameters) diff --git a/docs/modules/volume.md b/docs/modules/volume.md index 108c4a7f..495b716b 100644 --- a/docs/modules/volume.md +++ b/docs/modules/volume.md @@ -75,6 +75,7 @@ Manage a Linode Volume. | `region` |
`str`
|
Optional
| The location to deploy the volume in. See https://api.linode.com/v4/regions | | `size` |
`int`
|
Optional
| The size of this volume, in GB. Be aware that volumes may only be resized up after creation. **(Updatable)** | | `attached` |
`bool`
|
Optional
| If true, the volume will be attached to a Linode. Otherwise, the volume will be detached. **(Default: `True`; Updatable)** | +| `encryption` |
`str`
|
Optional
| Enables encryption on the volume. Full disk encryption ensures the data stored on a block storage volume drive is secure. **(Choices: `disabled`, `enabled`)** | | `wait_timeout` |
`int`
|
Optional
| The amount of time, in seconds, to wait for a volume to have the active status. **(Default: `240`)** | | `source_volume_id` |
`int`
|
Optional
| The volume id of the desired volume to clone. | | `tags` |
`list`
|
Optional
| The tags to be attached to the volume. | diff --git a/plugins/modules/instance.py b/plugins/modules/instance.py index d7740953..3a7d5cda 100644 --- a/plugins/modules/instance.py +++ b/plugins/modules/instance.py @@ -524,6 +524,13 @@ ], editable=True, ), + "capabilities": SpecField( + type=FieldType.list, + element_type=FieldType.string, + description=[ + "Read-only. A list of capabilities this compute instance supports.", + ], + ), "placement_group": SpecField( type=FieldType.dict, suboptions=linode_instance_placement_group_spec, diff --git a/plugins/modules/placement_group.py b/plugins/modules/placement_group.py index 0e26c094..98b964fa 100644 --- a/plugins/modules/placement_group.py +++ b/plugins/modules/placement_group.py @@ -66,7 +66,6 @@ SPECDOC_META = SpecDocMeta( description=[ "Manage a Linode Placement Group.", - "NOTE: Placement Groups may not currently be available to all users.", ], requirements=global_requirements, author=global_authors, diff --git a/plugins/modules/placement_group_assign.py b/plugins/modules/placement_group_assign.py index 88cee007..0b98a6b7 100644 --- a/plugins/modules/placement_group_assign.py +++ b/plugins/modules/placement_group_assign.py @@ -50,7 +50,6 @@ SPECDOC_META = SpecDocMeta( description=[ "Manages a single assignment between a Linode and a Placement Group.", - "NOTE: Placement Groups may not currently be available to all users.", ], requirements=global_requirements, author=global_authors, diff --git a/plugins/modules/placement_group_info.py b/plugins/modules/placement_group_info.py index 7d3ccc06..d2c7522d 100644 --- a/plugins/modules/placement_group_info.py +++ b/plugins/modules/placement_group_info.py @@ -35,7 +35,6 @@ )._raw_json, ), ], - requires_beta=True, ) SPECDOC_META = module.spec diff --git a/plugins/modules/placement_group_list.py b/plugins/modules/placement_group_list.py index 5a3cd478..af4d4583 100644 --- a/plugins/modules/placement_group_list.py +++ b/plugins/modules/placement_group_list.py @@ -19,7 +19,6 @@ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-placement-groups", result_samples=docs.result_placement_groups_samples, examples=docs.specdoc_examples, - requires_beta=True, ) SPECDOC_META = module.spec diff --git a/plugins/modules/volume.py b/plugins/modules/volume.py index d6cd04aa..fbae2d26 100644 --- a/plugins/modules/volume.py +++ b/plugins/modules/volume.py @@ -74,6 +74,14 @@ "Otherwise, the volume will be detached." ], ), + "encryption": SpecField( + type=FieldType.string, + description=[ + "Enables encryption on the volume. Full disk encryption ensures " + "the data stored on a block storage volume drive is secure." + ], + choices=["disabled", "enabled"], + ), "wait_timeout": SpecField( type=FieldType.integer, default=240, diff --git a/pyproject.toml b/pyproject.toml index f1391246..4fedc6f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,8 @@ disable = [ "missing-timeout", "use-sequence-for-iteration", "broad-exception-raised", - "fixme" + "fixme", ] +max-positional-arguments = 12 py-version = "3.8" extension-pkg-whitelist = "math" diff --git a/requirements.txt b/requirements.txt index e855f89d..3fba61ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ linode-api4>=5.22.0 polling>=0.3.2 -types-requests==2.32.0.20240914 +types-requests==2.32.0.20241016 ansible-specdoc>=0.0.15 diff --git a/tests/integration/targets/instance_basic/tasks/main.yaml b/tests/integration/targets/instance_basic/tasks/main.yaml index 1366390b..7676aa3b 100644 --- a/tests/integration/targets/instance_basic/tasks/main.yaml +++ b/tests/integration/targets/instance_basic/tasks/main.yaml @@ -133,6 +133,7 @@ - info_id.instance.region == pg_region - info_id.configs|length == 1 - info_id.networking.ipv4.public[0].address != None + - info_id.instance.capabilities == create.instance.capabilities - name: Get info about the instance by label linode.cloud.instance_info: diff --git a/tests/integration/targets/instance_config_vlan/tasks/main.yaml b/tests/integration/targets/instance_config_vlan/tasks/main.yaml index 6b106c05..d5b9fce7 100644 --- a/tests/integration/targets/instance_config_vlan/tasks/main.yaml +++ b/tests/integration/targets/instance_config_vlan/tasks/main.yaml @@ -11,7 +11,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 20 configs: - label: cool-config devices: @@ -43,7 +43,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 20 configs: - label: cool-config devices: @@ -76,7 +76,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 20 configs: - label: cool-config devices: diff --git a/tests/integration/targets/instance_config_vpc/tasks/main.yaml b/tests/integration/targets/instance_config_vpc/tasks/main.yaml index e17c3f60..51dbc208 100644 --- a/tests/integration/targets/instance_config_vpc/tasks/main.yaml +++ b/tests/integration/targets/instance_config_vpc/tasks/main.yaml @@ -31,7 +31,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 20 configs: - label: cool-config devices: @@ -84,7 +84,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 30 configs: - label: cool-config devices: @@ -126,7 +126,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 30 configs: - label: cool-config devices: diff --git a/tests/integration/targets/volume_basic/tasks/main.yaml b/tests/integration/targets/volume_basic/tasks/main.yaml index 856a29f9..d3f99639 100644 --- a/tests/integration/targets/volume_basic/tasks/main.yaml +++ b/tests/integration/targets/volume_basic/tasks/main.yaml @@ -95,6 +95,7 @@ that: - volume_info_label.volume.linode_id == attach_volume.volume.linode_id - volume_info_label.volume.size == attach_volume.volume.size + - volume_info_label.volume.encryption == attach_volume.volume.encryption - name: Detach the volume linode.cloud.volume: diff --git a/tests/integration/targets/vpc_ip_list/tasks/main.yaml b/tests/integration/targets/vpc_ip_list/tasks/main.yaml index 3069141d..de023e06 100644 --- a/tests/integration/targets/vpc_ip_list/tasks/main.yaml +++ b/tests/integration/targets/vpc_ip_list/tasks/main.yaml @@ -45,7 +45,7 @@ disks: - label: test-disk filesystem: ext4 - size: 10 + size: 25 configs: - label: cool-config devices: