├── .github ├── CODEOWNERS ├── dependabot.yml └── workflows │ └── ci.yml ├── .github_changelog_generator ├── .gitignore ├── .markdownlint.yaml ├── .rubocop.yml ├── .rubocop_todo.yml ├── .yamllint ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Policyfile.rb ├── README.md ├── RELEASE.md ├── Rakefile ├── TESTING.md ├── chefignore ├── kitchen.yml ├── libraries ├── dnsimple_provider.rb ├── dnsimple_resource.rb ├── provider_dnsimple_certificate.rb ├── provider_dnsimple_record.rb ├── resource_dnsimple_certificate.rb └── resource_dnsimple_record.rb ├── metadata.rb ├── recipes └── default.rb ├── spec ├── libraries │ ├── provider_dnsimple_certificate_spec.rb │ └── provider_dnsimple_record_spec.rb ├── recipes │ └── default_spec.rb ├── spec_helper.rb └── support │ └── shared_context.rb └── test ├── cookbooks └── test │ ├── LICENSE │ ├── README.md │ ├── metadata.rb │ └── recipes │ ├── create_record.rb │ ├── default.rb │ ├── reset_test_environment.rb │ └── update_record.rb └── integration ├── create_record ├── controls │ └── create_record.rb ├── inspec.yml └── libraries │ └── dnsimple_zone.rb └── update_record ├── controls └── update_record.rb ├── inspec.yml └── libraries └── dnsimple_zone.rb /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @dnsimple/platform 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: weekly 8 | labels: 9 | - task 10 | - dependencies 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | on: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | cookstyle: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout Code 20 | uses: actions/checkout@v4 21 | - name: Install Chef Workstation 22 | uses: actionshub/chef-install@main 23 | - name: Run Cookstyle 24 | run: chef exec rake cookstyle 25 | env: 26 | CHEF_LICENSE: accept-no-persist 27 | 28 | markdownlint-cli: 29 | runs-on: ubuntu-latest 30 | steps: 31 | - name: Checkout Code 32 | uses: actions/checkout@v4 33 | - name: Run markdownlint-cli 34 | uses: nosborn/github-action-markdown-cli@v3.4.0 35 | with: 36 | files: . 37 | config_file: ".markdownlint.yaml" 38 | 39 | rspec: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Checkout Code 43 | uses: actions/checkout@v4 44 | - name: Install Chef Workstation 45 | uses: actionshub/chef-install@main 46 | - name: Install DNSimple gem 47 | run: chef gem install -N dnsimple -v '~> 9' 48 | env: 49 | CHEF_LICENSE: accept-no-persist 50 | - name: RSpec 51 | run: chef exec rake spec 52 | env: 53 | CHEF_LICENSE: accept-no-persist 54 | 55 | yamllint: 56 | runs-on: ubuntu-latest 57 | steps: 58 | - name: Checkout Code 59 | uses: actions/checkout@v4 60 | - name: Run YAML Lint 61 | uses: actionshub/yamllint@main 62 | 63 | integration: 64 | needs: 65 | - cookstyle 66 | - markdownlint-cli 67 | - rspec 68 | - yamllint 69 | runs-on: ubuntu-latest 70 | strategy: 71 | matrix: 72 | os: 73 | - 'centos-stream-9' 74 | - 'centos-stream-10' 75 | - 'rockylinux-8' 76 | - 'rockylinux-9' 77 | - 'ubuntu-2004' 78 | - 'ubuntu-2204' 79 | - 'ubuntu-2404' 80 | suite: 81 | - 'create' 82 | - 'update' 83 | fail-fast: false 84 | steps: 85 | - name: Checkout Code 86 | uses: actions/checkout@v4 87 | - name: Install Chef Workstation 88 | uses: actionshub/chef-install@main 89 | - name: Install DNSimple gem 90 | run: chef gem install -N dnsimple -v '~> 9' 91 | env: 92 | CHEF_LICENSE: accept-no-persist 93 | - name: Run Test Kitchen 94 | uses: actionshub/test-kitchen@main 95 | env: 96 | CHEF_LICENSE: accept-no-persist 97 | DNSIMPLE_ACCESS_TOKEN: ${{ secrets.DNSIMPLE_ACCESS_TOKEN }} 98 | DNSIMPLE_TEST_DOMAIN: ${{ matrix.suite }}-record-${{ matrix.os }}-dnsimple.xyz 99 | KITCHEN_LOCAL_YAML: kitchen.yml 100 | with: 101 | suite: ${{ matrix.suite }}-record 102 | os: ${{ matrix.os }} 103 | - name: Debug 104 | if: failure() 105 | run: | 106 | set -x 107 | sudo journalctl -l --since today 108 | KITCHEN_LOCAL_YAML=kitchen.yml DNSIMPLE_TEST_DOMAIN=${{ matrix.suite }}-record-${{ matrix.os }}-dnsimple.xyz /usr/bin/kitchen exec \ 109 | ${{ matrix.suite }}-record-${{ matrix.os }} -c "journalctl -l" 110 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | user=dnsimple 2 | project=chef-dnsimple 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | .cache 3 | .kitchen/ 4 | .kitchen.local.yml 5 | bin 6 | Berksfile.lock 7 | Gemfile.lock 8 | Policyfile.lock.json 9 | -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | default: true 3 | line-length: false 4 | no-multiple-blanks: false 5 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: .rubocop_todo.yml 2 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2024-04-03 13:43:12 UTC using RuboCop version 1.25.1. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | document-start: false 5 | line-length: 6 | max: 256 7 | level: warning 8 | truthy: 9 | ignore: | 10 | /.github/workflows/*.yml 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v4.5.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.5.0) (2024-05-08) 4 | 5 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v4.4.0...v4.5.0) 6 | 7 | **Merged pull requests:** 8 | 9 | - Switch dnsimple gem installation from gem\_package to chef\_gem [\#92](https://github.com/dnsimple/chef-dnsimple/pull/92) ([san983](https://github.com/san983)) 10 | 11 | ## [v4.4.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.4.0) (2024-05-08) 12 | 13 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v4.3.0...v4.4.0) 14 | 15 | **Implemented enhancements:** 16 | 17 | - Adds build\_essentinal into default recipe [\#91](https://github.com/dnsimple/chef-dnsimple/pull/91) ([san983](https://github.com/san983)) 18 | 19 | ## [v4.3.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.3.0) (2024-04-04) 20 | 21 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v4.2.0...v4.3.0) 22 | 23 | ## [v4.2.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.2.0) (2024-04-04) 24 | 25 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v4.1.0...v4.2.0) 26 | 27 | **Implemented enhancements:** 28 | 29 | - Moves to unified\_mode [\#89](https://github.com/dnsimple/chef-dnsimple/pull/89) ([san983](https://github.com/san983)) 30 | - Assign to the right github team [\#88](https://github.com/dnsimple/chef-dnsimple/pull/88) ([san983](https://github.com/san983)) 31 | 32 | ## [v4.1.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.1.0) (2023-12-21) 33 | 34 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v4.0.0...v4.1.0) 35 | 36 | **Closed issues:** 37 | 38 | - Upgrade dnsimple gem from 7 to 8 [\#81](https://github.com/dnsimple/chef-dnsimple/issues/81) 39 | 40 | **Merged pull requests:** 41 | 42 | - fix missing changelog entries [\#87](https://github.com/dnsimple/chef-dnsimple/pull/87) ([AGS4NO](https://github.com/AGS4NO)) 43 | - Bump actions/checkout from 3 to 4 [\#86](https://github.com/dnsimple/chef-dnsimple/pull/86) ([dependabot[bot]](https://github.com/apps/dependabot)) 44 | - Patch/dependencies update [\#85](https://github.com/dnsimple/chef-dnsimple/pull/85) ([AGS4NO](https://github.com/AGS4NO)) 45 | - Bump nosborn/github-action-markdown-cli from 3.2.0 to 3.3.0 [\#84](https://github.com/dnsimple/chef-dnsimple/pull/84) ([dependabot[bot]](https://github.com/apps/dependabot)) 46 | - update workflow jobs, add dependabot for GH actions [\#83](https://github.com/dnsimple/chef-dnsimple/pull/83) ([AGS4NO](https://github.com/AGS4NO)) 47 | - kitchen chef-client v18 [\#82](https://github.com/dnsimple/chef-dnsimple/pull/82) ([AGS4NO](https://github.com/AGS4NO)) 48 | - Deprecates Chef Delivery CLI usage [\#79](https://github.com/dnsimple/chef-dnsimple/pull/79) ([san983](https://github.com/san983)) 49 | 50 | ## [v4.0.0](https://github.com/dnsimple/chef-dnsimple/tree/v4.0.0) (2021-10-29) 51 | 52 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.4.0...v4.0.0) 53 | 54 | **Implemented enhancements:** 55 | 56 | - Update dnsimple ruby gem version [\#75](https://github.com/dnsimple/chef-dnsimple/issues/75) 57 | 58 | **Merged pull requests:** 59 | 60 | - Use time to get new precisions [\#78](https://github.com/dnsimple/chef-dnsimple/pull/78) ([onlyhavecans](https://github.com/onlyhavecans)) 61 | - Update DNSimple gem \(rename certificate expires\_on to expires\_at\) [\#77](https://github.com/dnsimple/chef-dnsimple/pull/77) ([onlyhavecans](https://github.com/onlyhavecans)) 62 | - CentOS 6 EOL, add CentOS 8 to actions CI [\#76](https://github.com/dnsimple/chef-dnsimple/pull/76) ([AGS4NO](https://github.com/AGS4NO)) 63 | - Adds CI to GitHub Actions [\#74](https://github.com/dnsimple/chef-dnsimple/pull/74) ([san983](https://github.com/san983)) 64 | - Fix Travis build [\#73](https://github.com/dnsimple/chef-dnsimple/pull/73) ([san983](https://github.com/san983)) 65 | 66 | ## [v3.4.0](https://github.com/dnsimple/chef-dnsimple/tree/v3.4.0) (2021-05-14) 67 | 68 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.3.0...v3.4.0) 69 | 70 | **Merged pull requests:** 71 | 72 | - Enhancement/focal support [\#72](https://github.com/dnsimple/chef-dnsimple/pull/72) ([AGS4NO](https://github.com/AGS4NO)) 73 | 74 | ## [v3.3.0](https://github.com/dnsimple/chef-dnsimple/tree/v3.3.0) (2021-01-21) 75 | 76 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.2.0...v3.3.0) 77 | 78 | **Merged pull requests:** 79 | 80 | - Updates chef-infra client to v16 [\#71](https://github.com/dnsimple/chef-dnsimple/pull/71) ([AGS4NO](https://github.com/AGS4NO)) 81 | - Updates Travis tests to Bionic distribution. [\#69](https://github.com/dnsimple/chef-dnsimple/pull/69) ([AGS4NO](https://github.com/AGS4NO)) 82 | 83 | ## [v3.2.0](https://github.com/dnsimple/chef-dnsimple/tree/v3.2.0) (2020-02-11) 84 | 85 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.1.0...v3.2.0) 86 | 87 | **Implemented enhancements:** 88 | 89 | - Filter the record lookup [\#67](https://github.com/dnsimple/chef-dnsimple/pull/67) ([onlyhavecans](https://github.com/onlyhavecans)) 90 | 91 | **Closed issues:** 92 | 93 | - Depfu Error: No dependency files found [\#68](https://github.com/dnsimple/chef-dnsimple/issues/68) 94 | 95 | ## [v3.1.0](https://github.com/dnsimple/chef-dnsimple/tree/v3.1.0) (2019-12-04) 96 | 97 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.0.1...v3.1.0) 98 | 99 | **Merged pull requests:** 100 | 101 | - Lint to latest codestyle [\#66](https://github.com/dnsimple/chef-dnsimple/pull/66) ([onlyhavecans](https://github.com/onlyhavecans)) 102 | - Move fully to Dokken & a single kitchen configuration [\#65](https://github.com/dnsimple/chef-dnsimple/pull/65) ([onlyhavecans](https://github.com/onlyhavecans)) 103 | - Trial CircleCI for builds [\#63](https://github.com/dnsimple/chef-dnsimple/pull/63) ([martinisoft](https://github.com/martinisoft)) 104 | - Test chef14 [\#62](https://github.com/dnsimple/chef-dnsimple/pull/62) ([onlyhavecans](https://github.com/onlyhavecans)) 105 | - Test 18.04 [\#61](https://github.com/dnsimple/chef-dnsimple/pull/61) ([onlyhavecans](https://github.com/onlyhavecans)) 106 | 107 | ## [v3.0.1](https://github.com/dnsimple/chef-dnsimple/tree/v3.0.1) (2018-10-19) 108 | 109 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v3.0.0...v3.0.1) 110 | 111 | **Merged pull requests:** 112 | 113 | - Update our provider to match dnsimple-ruby 4.5.0 [\#60](https://github.com/dnsimple/chef-dnsimple/pull/60) ([martinisoft](https://github.com/martinisoft)) 114 | 115 | ## [v3.0.0](https://github.com/dnsimple/chef-dnsimple/tree/v3.0.0) (2018-08-08) 116 | 117 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v2.2.0...v3.0.0) 118 | 119 | **Fixed bugs:** 120 | 121 | - Rename 'name' property [\#56](https://github.com/dnsimple/chef-dnsimple/issues/56) 122 | 123 | **Merged pull requests:** 124 | 125 | - Upgrade to Chef 13.9+ [\#57](https://github.com/dnsimple/chef-dnsimple/pull/57) ([martinisoft](https://github.com/martinisoft)) 126 | 127 | ## [v2.2.0](https://github.com/dnsimple/chef-dnsimple/tree/v2.2.0) (2018-08-07) 128 | 129 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v2.1.1...v2.2.0) 130 | 131 | **Merged pull requests:** 132 | 133 | - Deprecate the 2.x series with log warnings [\#59](https://github.com/dnsimple/chef-dnsimple/pull/59) ([martinisoft](https://github.com/martinisoft)) 134 | - Update copyrights [\#58](https://github.com/dnsimple/chef-dnsimple/pull/58) ([onlyhavecans](https://github.com/onlyhavecans)) 135 | 136 | ## [v2.1.1](https://github.com/dnsimple/chef-dnsimple/tree/v2.1.1) (2018-03-21) 137 | 138 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v2.1.0...v2.1.1) 139 | 140 | **Fixed bugs:** 141 | 142 | - Running integration tests with custom domain fails [\#52](https://github.com/dnsimple/chef-dnsimple/issues/52) 143 | 144 | **Merged pull requests:** 145 | 146 | - Bugfix: Correctly validate the test domain in Inspec [\#55](https://github.com/dnsimple/chef-dnsimple/pull/55) ([martinisoft](https://github.com/martinisoft)) 147 | - Bugfix: AAAA record validation in dnsimple\_record resource [\#54](https://github.com/dnsimple/chef-dnsimple/pull/54) ([martinisoft](https://github.com/martinisoft)) 148 | - Add all\_certificates endpoint and fix certificates spec [\#53](https://github.com/dnsimple/chef-dnsimple/pull/53) ([martinisoft](https://github.com/martinisoft)) 149 | - Use latest versions of images for testing [\#51](https://github.com/dnsimple/chef-dnsimple/pull/51) ([martinisoft](https://github.com/martinisoft)) 150 | - Testing to chef 13 [\#50](https://github.com/dnsimple/chef-dnsimple/pull/50) ([onlyhavecans](https://github.com/onlyhavecans)) 151 | 152 | ## [v2.1.0](https://github.com/dnsimple/chef-dnsimple/tree/v2.1.0) (2017-06-26) 153 | 154 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v2.0.1...v2.1.0) 155 | 156 | **Merged pull requests:** 157 | 158 | - Add Docs for dnsimple\_certificate [\#49](https://github.com/dnsimple/chef-dnsimple/pull/49) ([onlyhavecans](https://github.com/onlyhavecans)) 159 | - Feature/install certificate [\#48](https://github.com/dnsimple/chef-dnsimple/pull/48) ([aeden](https://github.com/aeden)) 160 | 161 | ## [v2.0.1](https://github.com/dnsimple/chef-dnsimple/tree/v2.0.1) (2017-05-18) 162 | 163 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v2.0.0...v2.0.1) 164 | 165 | **Fixed bugs:** 166 | 167 | - Re-release 2.0.0 with updated Stove [\#47](https://github.com/dnsimple/chef-dnsimple/issues/47) 168 | 169 | ## [v2.0.0](https://github.com/dnsimple/chef-dnsimple/tree/v2.0.0) (2017-04-24) 170 | 171 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.3.4...v2.0.0) 172 | 173 | **Fixed bugs:** 174 | 175 | - Force apt in the run list for ubuntu platforms [\#41](https://github.com/dnsimple/chef-dnsimple/pull/41) ([martinisoft](https://github.com/martinisoft)) 176 | 177 | **Closed issues:** 178 | 179 | - Chef 11 needs compat resources [\#45](https://github.com/dnsimple/chef-dnsimple/issues/45) 180 | 181 | **Merged pull requests:** 182 | 183 | - Replace fog with dnsimple and rewrite to Chef 12.5+ resource [\#46](https://github.com/dnsimple/chef-dnsimple/pull/46) ([martinisoft](https://github.com/martinisoft)) 184 | - It seems that Chef 11 and Compat resources no go [\#44](https://github.com/dnsimple/chef-dnsimple/pull/44) ([jjasghar](https://github.com/jjasghar)) 185 | - Update README.md [\#43](https://github.com/dnsimple/chef-dnsimple/pull/43) ([jjasghar](https://github.com/jjasghar)) 186 | 187 | ## [v1.3.4](https://github.com/dnsimple/chef-dnsimple/tree/v1.3.4) (2016-09-30) 188 | 189 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.3.3...v1.3.4) 190 | 191 | **Merged pull requests:** 192 | 193 | - Swap fog gem for fog-dnsimple [\#42](https://github.com/dnsimple/chef-dnsimple/pull/42) ([martinisoft](https://github.com/martinisoft)) 194 | 195 | ## [v1.3.3](https://github.com/dnsimple/chef-dnsimple/tree/v1.3.3) (2016-06-27) 196 | 197 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.3.2...v1.3.3) 198 | 199 | **Fixed bugs:** 200 | 201 | - getchef.com isn't our site anymore [\#37](https://github.com/dnsimple/chef-dnsimple/pull/37) ([jjasghar](https://github.com/jjasghar)) 202 | 203 | **Merged pull requests:** 204 | 205 | - Update Travis-CI builds to use Integration [\#40](https://github.com/dnsimple/chef-dnsimple/pull/40) ([martinisoft](https://github.com/martinisoft)) 206 | - Fix test suite names for kitchen [\#39](https://github.com/dnsimple/chef-dnsimple/pull/39) ([onlyhavecans](https://github.com/onlyhavecans)) 207 | - Remove 16.04 due to bento issues. Update Documents [\#38](https://github.com/dnsimple/chef-dnsimple/pull/38) ([onlyhavecans](https://github.com/onlyhavecans)) 208 | 209 | ## [v1.3.2](https://github.com/dnsimple/chef-dnsimple/tree/v1.3.2) (2016-06-24) 210 | 211 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.3.1...v1.3.2) 212 | 213 | **Merged pull requests:** 214 | 215 | - Move to cookstyle over chefstyle [\#36](https://github.com/dnsimple/chef-dnsimple/pull/36) ([onlyhavecans](https://github.com/onlyhavecans)) 216 | 217 | ## [v1.3.1](https://github.com/dnsimple/chef-dnsimple/tree/v1.3.1) (2016-06-10) 218 | 219 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.3.0...v1.3.1) 220 | 221 | **Merged pull requests:** 222 | 223 | - Update documentation with a correction for the token usage [\#35](https://github.com/dnsimple/chef-dnsimple/pull/35) ([martinisoft](https://github.com/martinisoft)) 224 | 225 | ## [v1.3.0](https://github.com/dnsimple/chef-dnsimple/tree/v1.3.0) (2016-06-10) 226 | 227 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/v1.2.0...v1.3.0) 228 | 229 | **Fixed bugs:** 230 | 231 | - DNSimple API authentication [\#24](https://github.com/dnsimple/chef-dnsimple/issues/24) 232 | 233 | **Merged pull requests:** 234 | 235 | - Support api tokens [\#33](https://github.com/dnsimple/chef-dnsimple/pull/33) ([martinisoft](https://github.com/martinisoft)) 236 | 237 | ## [v1.2.0](https://github.com/dnsimple/chef-dnsimple/tree/v1.2.0) (2016-06-10) 238 | 239 | [Full Changelog](https://github.com/dnsimple/chef-dnsimple/compare/3085b8987751eb58e112743ca037cfbda9189222...v1.2.0) 240 | 241 | **Fixed bugs:** 242 | 243 | - Fix ChefSpec Deprecation Warning [\#25](https://github.com/dnsimple/chef-dnsimple/issues/25) 244 | - centos-65 requires patch utility due to nokogiri, only build-essential ~\> 2.0.4 installs patch [\#21](https://github.com/dnsimple/chef-dnsimple/issues/21) 245 | - Fix converging in modern chef 11 and chef 12 [\#32](https://github.com/dnsimple/chef-dnsimple/pull/32) ([onlyhavecans](https://github.com/onlyhavecans)) 246 | - Cleanup testing [\#31](https://github.com/dnsimple/chef-dnsimple/pull/31) ([martinisoft](https://github.com/martinisoft)) 247 | 248 | **Closed issues:** 249 | 250 | - Use Fog DNSimple API Auth [\#27](https://github.com/dnsimple/chef-dnsimple/issues/27) 251 | - Ubuntu 14.04 package requirement [\#23](https://github.com/dnsimple/chef-dnsimple/issues/23) 252 | - Should have option to gracefully handle existing A record for CNAME create [\#18](https://github.com/dnsimple/chef-dnsimple/issues/18) 253 | - Release a new version to Chef Community site [\#11](https://github.com/dnsimple/chef-dnsimple/issues/11) 254 | - Add Test Kitchen [\#10](https://github.com/dnsimple/chef-dnsimple/issues/10) 255 | - Cookbook removes undesired records [\#9](https://github.com/dnsimple/chef-dnsimple/issues/9) 256 | - Should depend on 'build-essential' [\#7](https://github.com/dnsimple/chef-dnsimple/issues/7) 257 | - LWRP should use load\_current\_resource [\#2](https://github.com/dnsimple/chef-dnsimple/issues/2) 258 | 259 | **Merged pull requests:** 260 | 261 | - Update build status and metadata [\#30](https://github.com/dnsimple/chef-dnsimple/pull/30) ([martinisoft](https://github.com/martinisoft)) 262 | - Unpin build-essential, blocks many popular cookbooks from use [\#22](https://github.com/dnsimple/chef-dnsimple/pull/22) ([martinb3](https://github.com/martinb3)) 263 | - Support creating record with multiple content values [\#20](https://github.com/dnsimple/chef-dnsimple/pull/20) ([josacar](https://github.com/josacar)) 264 | - Use load\_current\_resource in lwrp [\#15](https://github.com/dnsimple/chef-dnsimple/pull/15) ([josacar](https://github.com/josacar)) 265 | - Integrate Test Kitchen [\#14](https://github.com/dnsimple/chef-dnsimple/pull/14) ([dje](https://github.com/dje)) 266 | - Configure attributes for ohai to workaround empty node.platform\_family [\#13](https://github.com/dnsimple/chef-dnsimple/pull/13) ([josacar](https://github.com/josacar)) 267 | - Avoid removing records with different type on create [\#12](https://github.com/dnsimple/chef-dnsimple/pull/12) ([josacar](https://github.com/josacar)) 268 | - Build Essential Dependancy [\#8](https://github.com/dnsimple/chef-dnsimple/pull/8) ([ichilton](https://github.com/ichilton)) 269 | - add platform support for rhel platforms and expand coverage for more debian platforms [\#6](https://github.com/dnsimple/chef-dnsimple/pull/6) ([mattkasa](https://github.com/mattkasa)) 270 | - Fix missing pkg dependencies, update to chef\_gem; add name to metadata. [\#5](https://github.com/dnsimple/chef-dnsimple/pull/5) ([mdxp](https://github.com/mdxp)) 271 | - Improvements to LWRP and Documentation [\#1](https://github.com/dnsimple/chef-dnsimple/pull/1) ([jtimberman](https://github.com/jtimberman)) 272 | 273 | 274 | 275 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 276 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the dnsimple Chef cookbook 2 | 3 | We're excited that you'd like to help us with our Chef cookbook project! 4 | 5 | ## Getting in contact with us 6 | 7 | In case you get stuck, feel free to email our helpful support staff at and we'll do our best to get you back up and running. 8 | 9 | ## Submitting issues 10 | 11 | When submitting an issue, please check the Issues section of this repository on Github to make sure it has not already been reported. If it has been reported, then please contribute to the conversation on the issue and provide any additional information you can. If it has not been reported, please be as detailed as possible. 12 | 13 | If your issue is in regards to security, please refer to our [security page](https://dnsimple.com/security) on how to submit those more directly to us. 14 | 15 | ## Contribution process 16 | 17 | 1. Fork the repository to your own account if you have not yet done do already. 18 | 2. Commit changes to a git branch that is named after the changes you wish to contribute. 19 | 3. Create a GitHub Pull Request for your change, following the [Pull Request Requirements](#pull-request-requirements) 20 | 4. Perform a [Code Review](#code-review-process) with the cookbook maintainers on the pull request. 21 | 22 | ### Pull Request Requirements 23 | 24 | In order to maintain a high standard of compatibility and consistency for the consumers of our cookbook we like to make sure all pull requests meet the following criteria: 25 | 26 | 1. **Tests:** To ensure high quality code and protect against regressions in the future we require all changes have ample test coverage. This does not mean 100% coverage or even specific types of coverage. See the TESTING.md file for details on how to run the test suite. 27 | 2. **Passing Continuous Integration (CI):** Speaking of tests, the contributed code must pass our full suite of tests on [GitHub](https://github.com/dnsimple/chef-dnsimple/actions) and show a green indicator meaning the latest build passes. If for some reason the build is failing before your pull request please raise the issue in the pull request so we may address it. 28 | 29 | ### Code Review Process 30 | 31 | Code review takes place in GitHub pull requests. See [this article](https://help.github.com/articles/about-pull-requests/) if you're not familiar with GitHub Pull Requests. 32 | 33 | Once you open a pull request, cookbook maintainers will review your code using the built-in code review process in Github PRs. The process at this point is as follows: 34 | 35 | 1. A cookbook maintainer will review your code and merge it if no changes are necessary. Your change will be merged into the cookbooks's `master` branch and will be noted in the cookbook's `CHANGELOG.md` at the time of release. 36 | 2. If a maintainer has feedback or questions on your changes they they will set `request changes` in the review and provide an explanation. 37 | 38 | ## Contribution Guidelines 39 | 40 | * **DO** include tests in your pull requests where applicable 41 | * **DONT** modify or change the version number in the metadata.rb as we prefer to control the release cycle ourselves and it makes for code merging headaches that make everyone involved pretty sad 42 | * **DONT** modify the CHANGELOG.md in your pull request as well. The maintainers will auto-generate this before a new release. 43 | * **DO** remember that humans are handling your contributions so please be nice and polite when discussing anything in your pull request. 44 | 45 | [DNSimple Security Page](https://dnsimple.com/security) 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright (c) 2014-2021 DNSimple Corporation 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /Policyfile.rb: -------------------------------------------------------------------------------- 1 | # A name that describes what the system you're building with Chef does. 2 | name 'dnsimple' 3 | 4 | # Where to find external cookbooks: 5 | default_source :supermarket 6 | 7 | # run_list: chef-client will run these recipes in the order specified. 8 | run_list 'test::default' 9 | named_run_list :create_test_records, %w(test::default test::reset_test_environment test::create_record) 10 | named_run_list :update_test_records, %w(test::default test::reset_test_environment test::update_record) 11 | 12 | # Specify a custom source for a single cookbook: 13 | # cookbook 'example_cookbook', path: '../cookbooks/example_cookbook' 14 | cookbook 'dnsimple', path: '.' 15 | cookbook 'test', path: 'test/cookbooks/test' 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | ![CI](https://github.com/dnsimple/chef-dnsimple/actions/workflows/ci.yml/badge.svg) 4 | 5 | A chef resource for automated DNS configuration via the [dnsimple](https://dnsimple.com/) API. 6 | 7 | ## DEPRECATION WARNING 8 | 9 | If you used the dnsimple_certificate resource, you'll want to do the following to migrate: 10 | 11 | * The resource property `expires_on` has changed to be `expires_at` to match the dnsimple gem 12 | 13 | ## Requirements 14 | 15 | * A [dnsimple](https://dnsimple.com/) account 16 | * An [account access token](https://developer.dnsimple.com/v2/#account-tokens-vs-user-tokens) from said dnsimple account 17 | * Chef Client 17 or newer 18 | 19 | ## Attributes 20 | 21 | * None 22 | 23 | ## Resources/Providers 24 | 25 | ### dnsimple\_record 26 | 27 | Manage a DNS record through the dnsimple API. This resource uses the 28 | [dnsimple Ruby library](https://rubygems.org/gems/dnsimple) to connect and use 29 | the dnsimple API. This resource also exposes a ChefSpec matcher for you to do 30 | unit testing as well. 31 | 32 | #### Record Actions 33 | 34 | | Action | Description | Default | 35 | |-----------|----------------------|---------| 36 | | *create* | Create the record. | Yes | 37 | | *update* | Update the record. | | 38 | | *destroy* | Destroy the record. | | 39 | 40 | #### Record Resource Properties 41 | 42 | | Property | Description | Required | Default | 43 | |----------------|----------------------------------|----------|----------------------------| 44 | | *domain* | Domain to manage | true | | 45 | | *record_name* | Name of the record | | '' | 46 | | *type* | Type of DNS record (see note) | true | | 47 | | *content* | String/Array content of records | true | | 48 | | *ttl* | Time to live | | 3600 | 49 | | *priority* | Priorty of record | | | 50 | | *regions* | Specific regions for this record | | | 51 | | *access_token* | DNSimple API token | true | | 52 | | *base_url* | DNSimple API url | | `https://api.dnsimple.com` | 53 | 54 | **Record Types**: The type of record can be one of the following: A, AAAA, 55 | CAA, CNAME, MX, NS, TXT, SPF, SRV, NAPTR, HINFO, SSHFP, ALIAS, URL or POOL. 56 | Some of these record types such as POOL require special account access which 57 | you can [contact support](https://dnsimple.com/contact) for access and 58 | assistance. 59 | 60 | **Note**: If you do not provide the record_name parameter, it will be blank 61 | and thus will be assumed to be the domain apex. The apex is the domain name 62 | without a subdomain. For example `bar.com` is the apex of `foo.bar.com`. 63 | 64 | **Regional Records**: Only certain plan types have regional records so it is 65 | blank by default. If you do not have this feature available it will return 66 | an error. 67 | 68 | #### Record Examples 69 | 70 | Note that these examples assume you have obtained an account level access token 71 | which is documented above (see Requirements). We're also assuming you're securely 72 | storing your API keys in [Chef Vault](https://docs.chef.io/chef_vault.html) but 73 | it is not a requirement. 74 | 75 | ```ruby 76 | dnsimple_record 'foo.com main server' do 77 | domain 'foo.com' 78 | type 'A' 79 | content '1.2.3.4' 80 | ttl 3600 81 | access_token chef_vault_item('secrets', 'dnsimple_token') 82 | action :create 83 | end 84 | 85 | dnsimple_record 'create a CNAME record for a Google Apps site calendar at calendar.example.com' do 86 | record_name 'calendar' 87 | content 'ghs.google.com' 88 | type 'CNAME' 89 | domain 'example.com' 90 | access_token chef_vault_item('secrets', 'dnsimple_token') 91 | action :create 92 | end 93 | 94 | dnsimple_record 'create an A record with multiple content values at servers.example.com' do 95 | record_name 'servers' 96 | content ['1.1.1.1', '2.2.2.2'] 97 | type 'A' 98 | domain 'example.com' 99 | access_token chef_vault_item('secrets', 'dnsimple_token') 100 | action :create 101 | end 102 | 103 | # Note: This only works with certain accounts, see the note above for 104 | # regional records! The Chef run will fail otherwise. 105 | dnsimple_record "create an A record in Tokyo only" do 106 | record_name 'myserverinjapan' 107 | content '2.2.2.2' 108 | type 'A' 109 | domain 'example.com' 110 | regions ['tko'] 111 | access_token chef_vault_item('secrets', 'dnsimple_token') 112 | action :create 113 | end 114 | ``` 115 | 116 | ### dnsimple\_certificate 117 | 118 | Download and install a certificate. Currently this only supports basic matched 119 | .crt & .key files. We would like to expand this to support all formats 120 | including java keystores. *PRs are welcome*! 121 | 122 | This resource uses the [dnsimple Ruby 123 | library](https://rubygems.org/gems/dnsimple) to connect and use the dnsimple 124 | API. This resource also exposes a ChefSpec matcher for you to do unit testing 125 | as well. 126 | 127 | #### Certificate Actions 128 | 129 | | Action | Description | Default | 130 | |-----------|-----------------------|---------| 131 | | *install* | Install the crt & key | Yes | 132 | 133 | #### Certificate Resource Properties 134 | 135 | | Property | Description | Required | Default | 136 | |-------------------|-----------------------------------|----------|----------------------------| 137 | | *install_path* | where the crt & key are installed | yes | | 138 | | *common_name* | certificate common name | yes | name of the resource | 139 | | *domain* | the main domain name on the crt | yes | | 140 | | *expires_at* | when the certificate expires | yes | | 141 | | *private_key_pem* | provide your own private key | no | | 142 | | *mode* | files mode | no | 0600 | 143 | | *owner* | files owner | no | root | 144 | | *group* | files group | no | root | 145 | | *access_token* | DNSimple API token | true | | 146 | | *base_url* | DNSimple API url | | `https://api.dnsimple.com` | 147 | 148 | #### Certificate Examples 149 | 150 | ```ruby 151 | dnsimple_certificate 'dnsimple.xyz certificate' do 152 | install_path '/etc/apache2/ssl' 153 | common_name 'www.dnsimple.xyz' 154 | domain 'dnsimple.xyz' 155 | expires_at '2019-09-08 17:21:29 UTC' 156 | mode '0755' 157 | owner 'web_admin' 158 | group 'web_admin' 159 | access_token chef_vault_item('secrets', 'dnsimple_token') 160 | end 161 | ``` 162 | 163 | ## Usage 164 | 165 | Add the dnsimple cookbook to your cookbook's metadata and it will automatically 166 | install the dnsimple gem and make the dnsimple\_record resource available. 167 | 168 | **Note:** If you want to avoid any issues with a maintenance window or service outage causing a Chef run failure, be sure to set the `ignore_failure` property to true as [documented in the common properties](https://docs.chef.io/resource_common.html#properties) which will only print warnings if records could not be updated during the Chef run. 169 | 170 | ## Testing 171 | 172 | See TESTING.md 173 | 174 | ## Contributing 175 | 176 | See CONTRIBUTING.md 177 | 178 | ## License 179 | 180 | Copyright 2024, DNSimple Corp. 181 | 182 | Licensed under the Apache License, Version 2.0. 183 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Releasing the DNSimple cookbook 2 | 3 | 1. See documentation in our wiki 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | task default: %w(test) 2 | task test: %w(delivery kitchen) 3 | task quick: :delivery 4 | 5 | require 'cookstyle' 6 | require 'rubocop/rake_task' 7 | RuboCop::RakeTask.new(:cookstyle) do |task| 8 | task.options = ['--display-cop-names', '--extra-details'] 9 | end 10 | 11 | require 'rspec/core/rake_task' 12 | RSpec::Core::RakeTask.new(:spec) do |task| 13 | task.rspec_opts = ['--color', '--format progress'] 14 | end 15 | 16 | desc 'Run linter and specs' 17 | task :delivery do 18 | g = 'Policyfile.lock.json' 19 | File.delete(g) if File.exist?(g) 20 | 21 | Rake::Task['cookstyle'].invoke 22 | Rake::Task['spec'].invoke 23 | end 24 | 25 | desc 'Run test kitchen with optional KITCHEN_ARGS if that env is present. Defaults suite test to "all" if no KITCHEN_REGEXP env var is present' 26 | task :kitchen do 27 | sh 'kitchen test ' << %W(#{ENV['KITCHEN_REGEXP'] || 'all'} #{ENV['KITCHEN_ARGS']}).reject(&:empty?).join(' ') 28 | end 29 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | ## Requirements 4 | 5 | You will need the following; 6 | 7 | * Docker Desktop 8 | * Chef-Workstation 9 | * The dnsimple gem installed into Chef-Workstation with `chef gem install dnsimple` 10 | * A [DNSimple Sandbox account](https://developer.dnsimple.com/sandbox/#testing-subscriptions) 11 | * A test domain created in sandbox set to your environment varible `DNSIMPLE_TEST_DOMAIN=domain.com` 12 | * Your sandbox API key saved to `DNSIMPLE_ACCESS_TOKEN=token` 13 | 14 | ### Running tests 15 | 16 | * run `chef exec rake quick` for unit and style tests. 17 | * run `chef exec rake kitchen` for kitchen tests 18 | * `chef exec rake` will run all tests 19 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | #* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen.yml* 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: dokken 4 | privileged: true 5 | chef_version: 18 6 | 7 | transport: 8 | name: dokken 9 | 10 | provisioner: 11 | name: dokken 12 | deprecations_as_errors: true 13 | always_update_cookbooks: true 14 | 15 | verifier: 16 | name: inspec 17 | inputs: 18 | dnsimple_token: <%= ENV['DNSIMPLE_ACCESS_TOKEN'] %> 19 | test_domain: <%= ENV['DNSIMPLE_TEST_DOMAIN'] || 'dnsimple.xyz' %> 20 | 21 | platforms: 22 | - name: ubuntu-20.04 23 | driver: 24 | image: dokken/ubuntu-20.04 25 | pid_one_command: /bin/systemd 26 | intermediate_instructions: 27 | - RUN /usr/bin/apt-get update 28 | 29 | - name: ubuntu-22.04 30 | driver: 31 | image: dokken/ubuntu-22.04 32 | pid_one_command: /bin/systemd 33 | intermediate_instructions: 34 | - RUN /usr/bin/apt-get update 35 | 36 | - name: ubuntu-24.04 37 | driver: 38 | image: dokken/ubuntu-24.04 39 | pid_one_command: /bin/systemd 40 | intermediate_instructions: 41 | - RUN /usr/bin/apt-get update 42 | 43 | - name: centos-stream-9 44 | driver: 45 | image: dokken/centos-stream-9 46 | pid_one_command: /usr/lib/systemd/systemd 47 | 48 | - name: centos-stream-10 49 | driver: 50 | image: dokken/centos-stream-10 51 | pid_one_command: /usr/lib/systemd/systemd 52 | 53 | - name: rockylinux-8 54 | driver: 55 | image: dokken/rockylinux-8 56 | pid_one_command: /usr/lib/systemd/systemd 57 | 58 | - name: rockylinux-9 59 | driver: 60 | image: dokken/rockylinux-9 61 | pid_one_command: /usr/lib/systemd/systemd 62 | 63 | suites: 64 | - name: create_record 65 | named_run_list: create_test_records 66 | attributes: 67 | dnsimple: 68 | access_token: <%= ENV['DNSIMPLE_ACCESS_TOKEN'] %> 69 | base_url: https://api.sandbox.dnsimple.com 70 | test_domain: <%= ENV['DNSIMPLE_TEST_DOMAIN'] || 'dnsimple.xyz' %> 71 | - name: update_record 72 | named_run_list: update_test_records 73 | attributes: 74 | dnsimple: 75 | access_token: <%= ENV['DNSIMPLE_ACCESS_TOKEN'] %> 76 | base_url: https://api.sandbox.dnsimple.com 77 | test_domain: <%= ENV['DNSIMPLE_TEST_DOMAIN'] || 'dnsimple.xyz' %> 78 | -------------------------------------------------------------------------------- /libraries/dnsimple_provider.rb: -------------------------------------------------------------------------------- 1 | class Chef 2 | class Provider 3 | class DnsimpleProvider < Chef::Provider 4 | attr_writer :dnsimple_client 5 | 6 | def dnsimple_client_account_id 7 | data = dnsimple_client_account.data 8 | if data.account.nil? 9 | raise 'Cannot find account id, please make sure you provide an account 10 | token and not a user token. See README for more information.' 11 | end 12 | data.account.id 13 | end 14 | 15 | def dnsimple_client_account 16 | dnsimple_client.identity.whoami 17 | rescue Dnsimple::AuthenticationFailed 18 | raise 'Authentication failed. Please check your access token' 19 | end 20 | 21 | def dnsimple_client 22 | require 'dnsimple' 23 | @dnsimple_client ||= Dnsimple::Client.new( 24 | access_token: new_resource.access_token, 25 | base_url: new_resource.base_url, 26 | user_agent: "chef-dnsimple #{run_context.cookbook_collection['dnsimple'].metadata.version}" 27 | ) 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /libraries/dnsimple_resource.rb: -------------------------------------------------------------------------------- 1 | class Chef 2 | class Resource 3 | class DnsimpleResource < Chef::Resource 4 | provides :dnsimple_resource 5 | unified_mode true 6 | 7 | attr_accessor :exists 8 | 9 | def after_created 10 | sensitive(true) 11 | end 12 | 13 | property :access_token, String, required: true, sensitive: true 14 | property :base_url, String, default: 'https://api.dnsimple.com' 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /libraries/provider_dnsimple_certificate.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: dnsimple 3 | # Library:: provider_dnsimple_certificate 4 | # 5 | # Copyright:: 2024 DNSimple Corp 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require_relative 'dnsimple_provider' 20 | 21 | class Chef 22 | class Provider 23 | class DnsimpleCertificate < DnsimpleProvider 24 | provides :dnsimple_certificate 25 | 26 | def load_current_resource 27 | @current_resource = Chef::Resource::DnsimpleCertificate.new(@new_resource.name) 28 | @current_resource.common_name(@new_resource.common_name) 29 | @current_resource.domain(@new_resource.domain) 30 | @current_resource.install_path(@new_resource.install_path) 31 | 32 | certificates = dnsimple_client.certificates.all_certificates(dnsimple_client_account_id, @new_resource.domain) 33 | @existing_certificate = certificates.data.detect do |certificate| 34 | (certificate.common_name == @new_resource.common_name) && (certificate.state == 'issued') && (Time.parse(certificate.expires_at) > Time.new.utc) 35 | end 36 | 37 | @current_resource.exists = !@existing_certificate.nil? 38 | if @current_resource.exists 39 | @current_resource.expires_at = Time.parse(@existing_certificate.expires_at).to_s 40 | @existing_certificate_bundle = dnsimple_client.certificates.download_certificate(dnsimple_client_account_id, @new_resource.domain, @existing_certificate.id).data 41 | @current_resource.server_pem = @existing_certificate_bundle.server 42 | @current_resource.chain_pem = @existing_certificate_bundle.chain 43 | # Allow override with custom private key 44 | if @new_resource.private_key_pem 45 | @current_resource.private_key_pem = @new_resource.private_key_pem 46 | else 47 | @existing_private_key = dnsimple_client.certificates.certificate_private_key(dnsimple_client_account_id, @new_resource.domain, @existing_certificate.id).data 48 | @current_resource.private_key_pem = @existing_private_key.private_key 49 | end 50 | end 51 | end 52 | 53 | action :install do 54 | if @current_resource.exists 55 | install_certificate 56 | else 57 | Chef::Log.info "DNSimple: no certificate found #{new_resource.certificate_common_name}" 58 | end 59 | end 60 | 61 | def install_certificate 62 | converge_by("install certificate #{current_resource.common_name} expiring #{current_resource.expires_at}") do 63 | declare_resource(:file, "#{current_resource.name}/#{current_resource.domain}.crt") do 64 | content "#{current_resource.server_pem}#{current_resource.chain_pem.join("\n")}" 65 | mode current_resource.mode 66 | owner current_resource.owner 67 | group current_resource.group 68 | end 69 | declare_resource(:file, "#{current_resource.name}/#{current_resource.domain}.key") do 70 | content current_resource.private_key_pem 71 | mode current_resource.mode 72 | owner current_resource.owner 73 | group current_resource.group 74 | sensitive true 75 | end 76 | end 77 | end 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /libraries/provider_dnsimple_record.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: dnsimple 3 | # Library:: provider_dnsimple_record 4 | # 5 | # Copyright:: 2024 DNSimple Corp 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require_relative 'dnsimple_provider' 20 | 21 | class Chef 22 | class Provider 23 | class DnsimpleRecord < DnsimpleProvider 24 | provides :dnsimple_record 25 | 26 | def load_current_resource 27 | @current_resource = Chef::Resource::DnsimpleRecord.new(@new_resource.name) 28 | @current_resource.record_name(@new_resource.record_name) 29 | @current_resource.domain(@new_resource.domain) 30 | @current_resource.type(@new_resource.type) 31 | 32 | record_filter = { name: @new_resource.record_name, type: @new_resource.type } 33 | records = dnsimple_client.zones.zone_records(dnsimple_client_account_id, 34 | @new_resource.domain, 35 | filter: record_filter) 36 | 37 | if records.data.length > 1 38 | Chef::Log.info "DNSimple: Multiple records found #{@new_resource.record_name}.#{@new_resource.domain}" \ 39 | " with type #{@new_resource.type}. This cookbook only modifies the first record." 40 | end 41 | 42 | @existing_record = records.data.first 43 | @current_resource.exists = !@existing_record.nil? 44 | end 45 | 46 | action :create do 47 | if @current_resource.exists 48 | Chef::Log.info "DNSimple: #{@new_resource} already exists - nothing to do." 49 | else 50 | create_record 51 | end 52 | end 53 | 54 | action :delete do 55 | if @current_resource.exists 56 | delete_record 57 | else 58 | Chef::Log.info "DNSimple: no record found #{new_resource.record_name}.#{new_resource.domain}" \ 59 | " with type #{new_resource.type}" 60 | end 61 | end 62 | 63 | action :update do 64 | if @current_resource.exists 65 | update_record 66 | else 67 | Chef::Log.info "DNSimple: no record found #{new_resource.record_name}.#{new_resource.domain}" \ 68 | " with type #{new_resource.type}" 69 | end 70 | end 71 | 72 | def create_record 73 | converge_by("create record #{new_resource.record_name} for domain #{new_resource.domain}") do 74 | dnsimple_client.zones.create_zone_record(dnsimple_client_account_id, 75 | new_resource.domain, 76 | **record_options 77 | ) 78 | Chef::Log.info "DNSimple: created #{new_resource.type} record for #{new_resource.name}.#{new_resource.domain}" 79 | end 80 | rescue Dnsimple::RequestError => e 81 | raise "DNSimple: Unable to complete create record request. Error: #{e.message}" 82 | end 83 | 84 | def delete_record 85 | converge_by("delete record #{@new_resource.record_name} from domain #{@new_resource.domain}") do 86 | dnsimple_client.zones.delete_zone_record(dnsimple_client_account_id, 87 | @current_resource.domain, 88 | existing_record_id 89 | ) 90 | Chef::Log.info "DNSimple: destroyed #{@new_resource.type} record " \ 91 | "for #{@new_resource.name}.#{@new_resource.domain}" 92 | end 93 | rescue Dnsimple::RequestError => e 94 | raise "DNSimple: Unable to complete create record request. Error: #{e.message}" 95 | end 96 | 97 | def update_record 98 | return unless changed_record? 99 | converge_by("update record #{new_resource.record_name} for domain #{new_resource.domain}") do 100 | dnsimple_client.zones.update_zone_record(dnsimple_client_account_id, 101 | new_resource.domain, 102 | existing_record_id, 103 | **record_options 104 | ) 105 | Chef::Log.info "DNSimple: updated #{new_resource.type} record for #{new_resource.name}.#{new_resource.domain}" 106 | end 107 | end 108 | 109 | def record_options 110 | options = { 111 | name: new_resource.record_name, type: new_resource.type, 112 | content: new_resource.content, ttl: new_resource.ttl, 113 | priority: new_resource.priority 114 | } 115 | options = options.merge(regions: new_resource.regions) if new_resource.regions 116 | options 117 | end 118 | 119 | def changed_record? 120 | (@existing_record.ttl != new_resource.ttl) || 121 | (@existing_record.content != new_resource.content) || 122 | (@existing_record.priority != new_resource.priority) || 123 | ((@existing_record.regions != new_resource.regions) if new_resource.regions) 124 | end 125 | 126 | def existing_record_id 127 | @existing_record.id 128 | end 129 | end 130 | end 131 | end 132 | -------------------------------------------------------------------------------- /libraries/resource_dnsimple_certificate.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: dnsimple 3 | # Library:: resource_dnsimple_certificate 4 | # 5 | # Copyright:: 2024 DNSimple Corp 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require_relative 'dnsimple_resource' 20 | 21 | class Chef 22 | class Resource 23 | class DnsimpleCertificate < DnsimpleResource 24 | resource_name :dnsimple_certificate 25 | provides :dnsimple_certificate 26 | 27 | allowed_actions :install 28 | default_action :install 29 | 30 | property :install_path, String, required: true 31 | property :common_name, String, name_property: true 32 | property :domain, String, required: true 33 | property :expires_at, String, required: true 34 | property :server_pem, String 35 | property :chain_pem, Array 36 | property :private_key_pem, String, sensitive: true 37 | property :mode, String, default: '0600' 38 | property :owner, String, default: 'root' 39 | property :group, String, default: 'root' 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /libraries/resource_dnsimple_record.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: dnsimple 3 | # Library:: resource_dnsimple_record 4 | # 5 | # Copyright:: 2024 DNSimple Corp 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require_relative 'dnsimple_resource' 20 | 21 | class Chef 22 | class Resource 23 | class DnsimpleRecord < DnsimpleResource 24 | resource_name :dnsimple_record 25 | provides :dnsimple_record 26 | 27 | allowed_actions :create, :delete, :update 28 | default_action :create 29 | 30 | property :record_name, String, default: '' 31 | property :domain, String 32 | property :type, String, equal_to: %w(A AAAA CAA CNAME MX NS TXT SPF SRV NAPTR HINFO SSHFP ALIAS URL POOL), required: true 33 | property :content, [String, Array] 34 | property :ttl, Integer, default: 3600 35 | property :priority, Integer 36 | property :regions, Array 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'dnsimple' 2 | maintainer 'DNSimple Corp' 3 | maintainer_email 'ops@dnsimple.com' 4 | license 'Apache-2.0' 5 | description 'Provides Chef Resource for automating DNS configuration with DNSimple' 6 | issues_url 'https://github.com/dnsimple/chef-dnsimple/issues' 7 | source_url 'https://github.com/dnsimple/chef-dnsimple' 8 | version '4.5.0' 9 | 10 | chef_version '>= 17' 11 | 12 | %w(amazon centos debian fedora freebsd redhat ubuntu).each do |os| 13 | supports os 14 | end 15 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | build_essential 'install tools' do 2 | compile_time true 3 | end 4 | 5 | chef_gem 'dnsimple' do 6 | version '~> 9' 7 | action :upgrade 8 | end 9 | -------------------------------------------------------------------------------- /spec/libraries/provider_dnsimple_certificate_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'dnsimple' 3 | require_relative '../../libraries/provider_dnsimple_certificate' 4 | require_relative '../../libraries/resource_dnsimple_certificate' 5 | 6 | describe Chef::Provider::DnsimpleCertificate do 7 | before(:each) do 8 | @node = stub_node(platform: 'ubuntu', version: '18.04') 9 | @events = Chef::EventDispatch::Dispatcher.new 10 | @new_resource = Chef::Resource::DnsimpleCertificate.new('/path/to/certificate.crt') 11 | @run_context = Chef::RunContext.new(@node, {}, @events) 12 | @current_resource = Chef::Resource::DnsimpleCertificate.new('/path/to/certificate.crt') 13 | @provider = Chef::Provider::DnsimpleCertificate.new(@new_resource, @run_context) 14 | end 15 | 16 | describe '#install' do 17 | before(:each) do 18 | @new_resource.access_token('this_is_a_token') 19 | @provider.dnsimple_client = client 20 | @new_resource.common_name = certificate_data[:common_name] 21 | @new_resource.expires_at = certificate_data[:expires_at] 22 | @new_resource.install_path = '/etc/nginx/ssl' 23 | @new_resource.domain = 'example.com' 24 | @provider.current_resource = @current_resource 25 | end 26 | 27 | let(:client) { instance_double(Dnsimple::Client, identity: identity, certificates: certificates) } 28 | let(:identity) { instance_double(Dnsimple::Client::Identity, whoami: whoami_response) } 29 | let(:whoami_response) { instance_double(Dnsimple::Response, data: data) } 30 | let(:data) { instance_double(Dnsimple::Struct::Whoami, account: account) } 31 | let(:account) { instance_double(Dnsimple::Struct::Account, id: 1) } 32 | let(:certificates) { instance_double(Dnsimple::Client::Certificates, all_certificates: certificate_list, download_certificate: certificate_bundle_response, certificate_private_key: private_key_bundle_response) } 33 | let(:certificate_list) { instance_double(Dnsimple::CollectionResponse, data: [certificate]) } 34 | let(:certificate) { instance_double(Dnsimple::Struct::Certificate, id: certificate_data[:id], common_name: certificate_data[:common_name], expires_at: certificate_data[:expires_at], state: 'issued') } 35 | let(:certificate_bundle_response) { instance_double(Dnsimple::Response, data: certificate_bundle) } 36 | let(:certificate_bundle) { instance_double(Dnsimple::Struct::CertificateBundle, server: 'server-pem', chain: ['chain-pem']) } 37 | let(:private_key_bundle_response) { instance_double(Dnsimple::Response, data: private_key_bundle) } 38 | let(:private_key_bundle) { instance_double(Dnsimple::Struct::CertificateBundle, private_key: 'private-key-pem') } 39 | let(:certificate_data) do 40 | { 41 | id: 1, 42 | common_name: 'www.example.com', 43 | expires_at: next_year.to_s, 44 | } 45 | end 46 | let(:next_year) { Time.now.utc + (60 * 60 * 24 * 365) } 47 | 48 | context 'if the certificate exists' do 49 | it 'installs the certificate' do 50 | @provider.run_action(:install) 51 | expect(@new_resource).to be_updated 52 | end 53 | end 54 | 55 | it 'implements the load_current_resource interface' do 56 | expect { @provider.load_current_resource }.to_not raise_exception 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /spec/libraries/provider_dnsimple_record_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'dnsimple' 3 | require_relative '../../libraries/provider_dnsimple_record' 4 | require_relative '../../libraries/resource_dnsimple_record' 5 | 6 | describe Chef::Provider::DnsimpleRecord do 7 | before(:each) do 8 | @node = stub_node(platform: 'ubuntu', version: '18.04') 9 | @events = Chef::EventDispatch::Dispatcher.new 10 | @run_context = Chef::RunContext.new(@node, {}, @events) 11 | @new_resource = Chef::Resource::DnsimpleRecord.new('record_name') 12 | @current_resource = Chef::Resource::DnsimpleRecord.new('record_name') 13 | @provider = Chef::Provider::DnsimpleRecord.new(@new_resource, @run_context) 14 | end 15 | 16 | describe '#create_record' do 17 | before(:each) do 18 | @new_resource.access_token('this_is_a_token') 19 | @provider.dnsimple_client = client 20 | @new_resource.record_name = dns_record[:name] 21 | @new_resource.type = dns_record[:type] 22 | @new_resource.content = dns_record[:content] 23 | @new_resource.domain = dns_record[:domain] 24 | @provider.current_resource = @current_resource 25 | end 26 | 27 | let(:client) { instance_double(Dnsimple::Client, identity: identity, zones: zones) } 28 | let(:identity) { instance_double(Dnsimple::Client::Identity, whoami: response) } 29 | let(:response) { instance_double(Dnsimple::Response, data: data) } 30 | let(:data) { instance_double(Dnsimple::Struct::Whoami, account: account) } 31 | let(:account) { instance_double(Dnsimple::Struct::Account, id: 1) } 32 | let(:zones) { instance_double(Dnsimple::Client::ZonesService, zone_records: zone_records, create_zone_record: zone_record) } 33 | let(:zone_records) { instance_double(Dnsimple::CollectionResponse, data: []) } 34 | let(:zone_record) { instance_double(Dnsimple::Struct::ZoneRecord, name: 'example_record') } 35 | let(:dns_record) do 36 | { 37 | name: 'test_record', 38 | domain: 'example.com', 39 | type: 'A', 40 | content: '1.2.3.4', 41 | ttl: 60, 42 | } 43 | end 44 | 45 | it 'updates the resource if the record does not exist' do 46 | @provider.run_action(:create) 47 | expect(@new_resource).to be_updated 48 | end 49 | 50 | it 'implements the load_current_resource interface' do 51 | expect { @provider.load_current_resource }.to_not raise_exception 52 | end 53 | 54 | context 'when it fails type validation' do 55 | it 'raises an exception' do 56 | expect { @new_resource.type = 'AA' }.to \ 57 | raise_exception(Chef::Exceptions::ValidationFailed, /Option type must be equal to one of:/) 58 | end 59 | end 60 | 61 | context 'when it fails request validation' do 62 | before do 63 | allow(zones).to receive(:create_zone_record) 64 | .and_raise(Dnsimple::RequestError, request_error) 65 | end 66 | 67 | let(:zones) { instance_double(Dnsimple::Client::ZonesService) } 68 | let(:request_error) do 69 | double('request_error', headers: '', response: request_error_response) 70 | end 71 | let(:request_error_response) do 72 | double('response', code: '405', message: 'Method Not Allowed') 73 | end 74 | 75 | it 'raises exception which fails the chef run' do 76 | expect { @provider.create_record }.to \ 77 | raise_exception(RuntimeError, 78 | 'DNSimple: Unable to complete create record request. Error: 405 Method Not Allowed') 79 | end 80 | end 81 | end 82 | 83 | describe '#delete_record' do 84 | before(:each) do 85 | @new_resource.access_token('this_is_a_token') 86 | @provider.dnsimple_client = client 87 | @new_resource.record_name = dns_record[:name] 88 | @new_resource.type = dns_record[:type] 89 | @new_resource.content = dns_record[:content] 90 | @new_resource.ttl = dns_record[:ttl] 91 | @new_resource.domain = dns_record_domain 92 | @provider.current_resource = @new_resource 93 | allow(zones).to receive(:delete_zone_record) 94 | end 95 | 96 | let(:client) { instance_double(Dnsimple::Client, identity: identity, zones: zones) } 97 | let(:identity) { instance_double(Dnsimple::Client::Identity, whoami: response) } 98 | let(:response) { instance_double(Dnsimple::Response, data: data) } 99 | let(:data) { instance_double(Dnsimple::Struct::Whoami, account: account) } 100 | let(:account) { instance_double(Dnsimple::Struct::Account, id: 1) } 101 | let(:zones) { instance_double(Dnsimple::Client::ZonesService, zone_records: zone_records) } 102 | let(:zone_records) { instance_double(Dnsimple::CollectionResponse, data: [zone_record]) } 103 | let(:zone_record) { instance_double(Dnsimple::Struct::ZoneRecord, **dns_record) } 104 | let(:dns_record_domain) { 'example.com' } 105 | let(:dns_record) do 106 | { 107 | id: 1234, 108 | name: 'test_record', 109 | type: 'A', 110 | content: '1.2.3.4', 111 | ttl: 60, 112 | } 113 | end 114 | 115 | context 'if the record exists' do 116 | it 'updates the resource' do 117 | @provider.run_action(:delete) 118 | expect(@new_resource).to be_updated 119 | end 120 | end 121 | 122 | context 'if the record does not exist' do 123 | let(:zone_records) { instance_double(Dnsimple::CollectionResponse, data: []) } 124 | 125 | it 'does not update the resource' do 126 | @provider.run_action(:delete) 127 | expect(@new_resource).to_not be_updated 128 | end 129 | end 130 | 131 | context 'when it fails validation' do 132 | before do 133 | allow(zones).to receive(:delete_zone_record) 134 | .and_raise(Dnsimple::RequestError, request_error) 135 | allow(@provider).to receive(:existing_record_id).and_return(0) 136 | end 137 | 138 | let(:zones) { instance_double(Dnsimple::Client::ZonesService) } 139 | let(:request_error) do 140 | double('request_error', headers: '', response: request_error_response) 141 | end 142 | let(:request_error_response) do 143 | double('response', code: '405', message: 'Method Not Allowed') 144 | end 145 | 146 | it 'raises exception which fails the chef run' do 147 | expect { @provider.delete_record }.to \ 148 | raise_exception(RuntimeError, 149 | 'DNSimple: Unable to complete create record request. Error: 405 Method Not Allowed') 150 | end 151 | end 152 | end 153 | 154 | describe '#update_record' do 155 | before(:each) do 156 | @new_resource.access_token('this_is_a_token') 157 | @provider.dnsimple_client = client 158 | @new_resource.record_name = dns_record[:name] 159 | @new_resource.type = dns_record[:type] 160 | @new_resource.content = dns_record[:content] 161 | @new_resource.priority = dns_record[:priority] 162 | @new_resource.ttl = new_ttl 163 | @new_resource.domain = dns_record_domain 164 | @provider.current_resource = @current_resource 165 | end 166 | 167 | let(:client) { instance_double(Dnsimple::Client, identity: identity, zones: zones) } 168 | let(:identity) { instance_double(Dnsimple::Client::Identity, whoami: response) } 169 | let(:response) { instance_double(Dnsimple::Response, data: data) } 170 | let(:data) { instance_double(Dnsimple::Struct::Whoami, account: account) } 171 | let(:account) { instance_double(Dnsimple::Struct::Account, id: 1) } 172 | let(:zones) { instance_double(Dnsimple::Client::ZonesService, zone_records: zone_records, update_zone_record: zone_record) } 173 | let(:zone_records) { instance_double(Dnsimple::CollectionResponse, data: [zone_record]) } 174 | let(:zone_record) { instance_double(Dnsimple::Struct::ZoneRecord, **dns_record) } 175 | let(:dns_record_domain) { 'example.com' } 176 | let(:dns_record) do 177 | { 178 | id: 1234, 179 | name: 'test_record', 180 | type: 'A', 181 | content: '1.2.3.4', 182 | priority: 0, 183 | ttl: 60, 184 | } 185 | end 186 | 187 | context 'if the resource exists' do 188 | context 'and the properites are different' do 189 | let(:new_ttl) { 120 } 190 | it 'updates the resource' do 191 | @provider.run_action(:update) 192 | expect(@new_resource).to be_updated 193 | end 194 | end 195 | 196 | context 'and the properites are the same' do 197 | let(:new_ttl) { dns_record[:ttl] } 198 | it 'does not update the resource' do 199 | @provider.run_action(:update) 200 | expect(@new_resource).to_not be_updated 201 | end 202 | end 203 | end 204 | end 205 | end 206 | -------------------------------------------------------------------------------- /spec/recipes/default_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'default recipe on ubuntu 18.04' do 4 | let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '18.04') } 5 | let(:chef_run) { runner.converge('dnsimple::default') } 6 | 7 | it 'converges successfully' do 8 | expect { :chef_run }.to_not raise_error 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # Added by ChefSpec 2 | require 'chefspec' 3 | 4 | # require files in spec/support/ directory 5 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } 6 | 7 | RSpec.configure do |config| 8 | # Specify the operating platform to mock Ohai data from 9 | config.platform = 'ubuntu' 10 | 11 | # Specify the operating version to mock Ohai data from 12 | config.version = '18.04' 13 | 14 | config.mock_with :rspec do |mocks| 15 | mocks.verify_partial_doubles = true 16 | end 17 | 18 | # Many RSpec users commonly either run the entire suite or an individual 19 | # file, and it's useful to allow more verbose output when running an 20 | # individual spec file. 21 | if config.files_to_run.one? 22 | # Use the documentation formatter for detailed output, 23 | # unless a formatter has already been configured 24 | # (e.g. via a command-line flag). 25 | config.default_formatter = 'doc' 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/support/shared_context.rb: -------------------------------------------------------------------------------- 1 | shared_context 'dnsimple' do 2 | let(:runner) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '18.04', step_into: ['dnsimple_record']) } 3 | let(:chef_run) { runner.converge(described_recipe) } 4 | end 5 | -------------------------------------------------------------------------------- /test/cookbooks/test/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright (c) 2014-2020 DNSimple Corporation 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /test/cookbooks/test/README.md: -------------------------------------------------------------------------------- 1 | # test cookbook 2 | 3 | This cookbook is used to do integration level testing in test kitchen. 4 | 5 | ## License and Authors 6 | 7 | Copyright:: 2024, DNSimple Corp. 8 | 9 | All rights reserved - Do Not Redistribute 10 | -------------------------------------------------------------------------------- /test/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | maintainer 'DNSimple Corp' 3 | maintainer_email 'ops@dnsimple.com' 4 | license 'Apache-2.0' 5 | description 'Tests dnsimple cookbook integration' 6 | version '0.1.0' 7 | 8 | depends 'dnsimple' 9 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/create_record.rb: -------------------------------------------------------------------------------- 1 | dnsimple_record 'arecord' do 2 | record_name 'arecord' 3 | type 'A' 4 | content '1.2.3.4' 5 | ttl 3600 6 | domain node['dnsimple']['test_domain'] 7 | access_token node['dnsimple']['access_token'] 8 | base_url node['dnsimple']['base_url'] 9 | end 10 | 11 | dnsimple_record 'arecord2' do 12 | record_name 'arecord' 13 | type 'A' 14 | content '1.2.3.4' 15 | ttl 3600 16 | domain node['dnsimple']['test_domain'] 17 | access_token node['dnsimple']['access_token'] 18 | base_url node['dnsimple']['base_url'] 19 | end 20 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'dnsimple' 2 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/reset_test_environment.rb: -------------------------------------------------------------------------------- 1 | dnsimple_record 'arecord_destroy' do 2 | record_name 'arecord' 3 | type 'A' 4 | content '1.2.3.4' 5 | ttl 3600 6 | domain node['dnsimple']['test_domain'] 7 | access_token node['dnsimple']['access_token'] 8 | base_url node['dnsimple']['base_url'] 9 | action :delete 10 | end 11 | 12 | dnsimple_record 'arecord2_destroy' do 13 | record_name 'arecord' 14 | type 'A' 15 | content '1.2.3.4' 16 | ttl 3600 17 | domain node['dnsimple']['test_domain'] 18 | access_token node['dnsimple']['access_token'] 19 | base_url node['dnsimple']['base_url'] 20 | action :delete 21 | end 22 | 23 | dnsimple_record 'cname_destroy' do 24 | record_name 'cnamerecord' 25 | type 'CNAME' 26 | domain node['dnsimple']['test_domain'] 27 | access_token node['dnsimple']['access_token'] 28 | base_url node['dnsimple']['base_url'] 29 | action :delete 30 | end 31 | 32 | dnsimple_record 'cname2_destroy' do 33 | record_name 'cnamerecord2' 34 | type 'CNAME' 35 | domain node['dnsimple']['test_domain'] 36 | access_token node['dnsimple']['access_token'] 37 | base_url node['dnsimple']['base_url'] 38 | action :delete 39 | end 40 | 41 | dnsimple_record 'cname_recreate' do 42 | record_name 'cnamerecord' 43 | type 'CNAME' 44 | ttl 3600 45 | content 'test.dnsimple.com' 46 | domain node['dnsimple']['test_domain'] 47 | access_token node['dnsimple']['access_token'] 48 | base_url node['dnsimple']['base_url'] 49 | action :create 50 | end 51 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/update_record.rb: -------------------------------------------------------------------------------- 1 | dnsimple_record 'cname_test' do 2 | record_name 'cnamerecord' 3 | type 'CNAME' 4 | ttl 60 5 | content "testing.#{node['dnsimple']['test_domain']}" 6 | domain node['dnsimple']['test_domain'] 7 | access_token node['dnsimple']['access_token'] 8 | base_url node['dnsimple']['base_url'] 9 | action :update 10 | end 11 | 12 | dnsimple_record 'cname2_test' do 13 | record_name 'cnamerecord2' 14 | type 'CNAME' 15 | ttl 60 16 | content "testing2.#{node['dnsimple']['test_domain']}" 17 | domain node['dnsimple']['test_domain'] 18 | access_token node['dnsimple']['access_token'] 19 | base_url node['dnsimple']['base_url'] 20 | action :update 21 | end 22 | -------------------------------------------------------------------------------- /test/integration/create_record/controls/create_record.rb: -------------------------------------------------------------------------------- 1 | token = input('dnsimple_token', description: 'The dnsimple API token') 2 | test_domain = input('test_domain', description: 'The domain to test against the API') 3 | 4 | describe dnsimple_zone(test_domain, 'arecord', token, 'A') do 5 | its('content') { should eq '1.2.3.4' } 6 | its('ttl') { should eq 3600 } 7 | end 8 | -------------------------------------------------------------------------------- /test/integration/create_record/inspec.yml: -------------------------------------------------------------------------------- 1 | name: create_record 2 | title: Create Zone Record Test 3 | maintainer: DNSimple Corp 4 | copyright: DNSimple Corp 5 | copyright_email: ops@dnsimple.com 6 | license: Apache 2 license 7 | summary: Confirms the test cookbook to create a record actually does so via the sandbox API 8 | version: 1.0.0 9 | supports: 10 | - os-family: linux 11 | 12 | inputs: 13 | - name: dnsimple_token 14 | description: The dnsimple API token 15 | type: string 16 | - name: test_domain 17 | description: The domain to test against the API 18 | type: string 19 | -------------------------------------------------------------------------------- /test/integration/create_record/libraries/dnsimple_zone.rb: -------------------------------------------------------------------------------- 1 | require 'dnsimple' 2 | 3 | class DnsimpleZone < Inspec.resource(1) 4 | name 'dnsimple_zone' 5 | desc 'Use the dnsimple_zone InSpec audit resource to verify zone data via the dnsimple API.' 6 | example " 7 | describe dnsimple_zone('example.com', 'server', 'abc321') do 8 | its('value') { should eq '1.2.3.4' } 9 | its('ttl') { should eq '3600' } 10 | end 11 | " 12 | 13 | def initialize(zone, name = nil, token = nil, type = nil) 14 | @zone = zone 15 | @name = name 16 | @token = token 17 | @type = type 18 | end 19 | 20 | def content 21 | response.content if response.respond_to?(:content) 22 | end 23 | 24 | def ttl 25 | response.ttl if response.respond_to?(:ttl) 26 | end 27 | 28 | def to_s 29 | "zone record lookup on #{@zone} for #{@name}" 30 | end 31 | 32 | private 33 | 34 | def response 35 | sandbox_url = 'https://api.sandbox.dnsimple.com' 36 | client = Dnsimple::Client.new(base_url: sandbox_url, access_token: @token) 37 | 38 | whoami = client.identity.whoami.data 39 | account_id = whoami.account.id 40 | 41 | filter = {} 42 | filter = { type: @type } if @type 43 | client.zones.all_zone_records(account_id, @zone, filter: filter).data.detect do |record| 44 | record.name == @name 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/integration/update_record/controls/update_record.rb: -------------------------------------------------------------------------------- 1 | token = input('dnsimple_token', description: 'The dnsimple API token') 2 | test_domain = input('test_domain', description: 'The domain to test against the API') 3 | 4 | describe dnsimple_zone(test_domain, 'cnamerecord', token, 'CNAME') do 5 | its('content') { should eq "testing.#{test_domain}" } 6 | its('ttl') { should eq 60 } 7 | end 8 | -------------------------------------------------------------------------------- /test/integration/update_record/inspec.yml: -------------------------------------------------------------------------------- 1 | name: update_record 2 | title: Update Zone Record Test 3 | maintainer: DNSimple Corp 4 | copyright: DNSimple Corp 5 | copyright_email: ops@dnsimple.com 6 | license: Apache 2 license 7 | summary: Confirms the test cookbook to create a record actually does so via the sandbox API 8 | version: 1.0.0 9 | supports: 10 | - os-family: linux 11 | 12 | inputs: 13 | - name: dnsimple_token 14 | description: The dnsimple API token 15 | type: string 16 | - name: test_domain 17 | description: The domain to test against the API 18 | type: string 19 | -------------------------------------------------------------------------------- /test/integration/update_record/libraries/dnsimple_zone.rb: -------------------------------------------------------------------------------- 1 | require 'dnsimple' 2 | 3 | class DnsimpleZone < Inspec.resource(1) 4 | name 'dnsimple_zone' 5 | desc 'Use the dnsimple_zone InSpec audit resource to verify zone data via the dnsimple API.' 6 | example " 7 | describe dnsimple_zone('example.com', 'server', 'abc321') do 8 | its('value') { should eq '1.2.3.4' } 9 | its('ttl') { should eq '3600' } 10 | end 11 | " 12 | 13 | def initialize(zone, name = nil, token = nil, type = nil) 14 | @zone = zone 15 | @name = name 16 | @token = token 17 | @type = type 18 | end 19 | 20 | def content 21 | response.content if response.respond_to?(:content) 22 | end 23 | 24 | def ttl 25 | response.ttl if response.respond_to?(:ttl) 26 | end 27 | 28 | def to_s 29 | "zone record lookup on #{@zone} for #{@name}" 30 | end 31 | 32 | private 33 | 34 | def response 35 | sandbox_url = 'https://api.sandbox.dnsimple.com' 36 | client = Dnsimple::Client.new(base_url: sandbox_url, access_token: @token) 37 | 38 | whoami = client.identity.whoami.data 39 | account_id = whoami.account.id 40 | 41 | filter = {} 42 | filter = { type: @type } if @type 43 | client.zones.all_zone_records(account_id, @zone, filter: filter).data.detect do |record| 44 | record.name == @name 45 | end 46 | end 47 | end 48 | --------------------------------------------------------------------------------