├── .github └── workflows │ ├── cli-release-trigger.yml │ └── test.yaml ├── LICENSE.txt ├── README.md ├── bin └── deploy ├── go.mod ├── openapi.json └── version /.github/workflows/cli-release-trigger.yml: -------------------------------------------------------------------------------- 1 | name: Trigger CLI Release 2 | on: 3 | release: 4 | types: [ published ] 5 | jobs: 6 | trigger-cli-release: 7 | runs-on: ubuntu-22.04 8 | steps: 9 | - name: Generate App Installation Token 10 | id: generate_token 11 | uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # pin@v1 12 | with: 13 | app_id: ${{ secrets.CLI_RELEASE_APP_ID }} 14 | private_key: ${{ secrets.CLI_RELEASE_PRIVATE_KEY }} 15 | repository: linode/linode-cli 16 | 17 | - name: Repository Dispatch 18 | uses: peter-evans/repository-dispatch@26b39ed245ab8f31526069329e112ab2fb224588 # pin@v2 19 | with: 20 | token: ${{ steps.generate_token.outputs.token }} 21 | repository: linode/linode-cli 22 | event-type: cli-release 23 | client-payload: '{"spec_version": "${{ github.event.release.tag_name }}"}' 24 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Python package 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - name: Set up Python 11 | uses: actions/setup-python@v2 12 | with: 13 | python-version: '3.9' 14 | architecture: 'x64' 15 | - name: Cache pip 16 | uses: actions/cache@v4 17 | with: 18 | path: ~/.cache/pip 19 | # Look to see if there is a cache hit for the corresponding requirements file 20 | key: ${{ runner.os }}-pip-${{ hashFiles('./ci/requirements.txt') }} 21 | restore-keys: | 22 | ${{ runner.os }}-pip- 23 | ${{ runner.os }}- 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install openapi3 28 | - name: openapi linter 29 | run: | 30 | python -m openapi3 openapi.yaml 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linode OpenAPI 3 2 | 3 | [![Build Status](https://travis-ci.com/linode/linode-api-docs.svg?branch=master)](https://travis-ci.com/linode/linode-api-docs) 4 | 5 | This is the Linode API OpenAPI 3 Schema 6 | 7 | ## Requirements 8 | 9 | The linter used for the OpenAPI spec is written in python3. 10 | A virtualenv is recommended for local work. 11 | 12 | ``` 13 | virtualenv -p python3 venv 14 | source venv/bin/activate 15 | pip install -r requirements.txt 16 | ``` 17 | 18 | ## Development 19 | 20 | The spec can be linted using the `openapi3` module. 21 | 22 | ``` 23 | python -m openapi3 openapi.yaml 24 | ``` 25 | 26 | ### Versioning 27 | 28 | When making a new release you **must** tag the release with the correct semantic versioning-compliant version string so that all versions are populated appropriately. 29 | There is a `./bin/deploy` helper which will help with this process. 30 | 31 | ``` 32 | ./bin/deploy 0.1.0 33 | ``` 34 | 35 | ## Spec Extensions 36 | 37 | The OpenAPI specification supports vendor-specific extensions prefixed with an 38 | `x-` in the attribute name. The following extensions are created by Linode for 39 | use in our spec: 40 | 41 | Attribute | Location | Type | Supported By | Explanation 42 | ---|---|---|---|--- 43 | `x-linode-filterable` | schema properties | boolean | | If `true`, indicates that this property may be included in an X-Filter header 44 | `x-linode-grant` | method | string | | The level of access a user must have in order to call this endpoint. 45 | `x-linode-cli-display` | schema properties | integer | linode-cli | If truthy, this property will be displayed in the Linode CLI. The numeric value determines the ordering of the displayed columns, left to right. 46 | `x-linode-cli-color` | schema properties | object | linode-cli | A mapping of possible property values to color codes understood by python's [colorclass module](https://pypi.python.org/pypi/colorclass). Must include a `default_`, used for any value that doesn't match one of the keys. 47 | `x-linode-cli-format` | schema properties | string | linode-cli | Overrides the value of the "format" field for this property, but for the CLI only. Valid values are `file` and `json`. 48 | `x-linode-cli-command` | path | string | linode-cli | The command group the methods of this path fall into when generating commands in the `linode-cli ` format. 49 | `x-linode-cli-action` | method | string | linode-cli | The action this method will be mapped to when generating commands in the `linode-cli ` format. 50 | `x-linode-cli-skip` | method | boolean | linode-cli | If true, the CLI will not expose this action. 51 | `x-linode-redoc-load-ids`| operation | boolean | If true, ReDoc will load this path and print a bulleted list of IDs. This only works on public collections. 52 | `x-linode-ref-name`| keyword | string | [Linode Developer's Site](https://github.com/linode/developers) | Provides a mechanism by which the Developer's site can generate a dropdown menu with an Object's name when using the `oneOf` keyword with a `discriminator`. **Note**: This front end functionality is currently being developed. 53 | `x-linode-cli-rows`| media type | array | linode-cli | A list of JSON paths where the CLI can find the value it should treat as table rows. Only needed for irregular endpoints. 54 | `x-linode-cli-use-schema` | media type | schema or $ref | linode-cli | The schema the CLI should use when showing a row for this response. Use with `x-linode-cli-rows`. 55 | `x-linode-cli-nested-list` | media type | string | linode-cli | The name of the property defined by this response body's schema that is a nested list. Items in the list will be broken out into rows in the CLI's output. 56 | `x-linode-cli-allowed-defaults` | requestBody | list of string | linode-cli | A list of defaults this action should accept from the CLI. Valid values are "region", "type", and "image" 57 | -------------------------------------------------------------------------------- /bin/deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git_tag="" 4 | version="" 5 | version_regex="[0-9]+\.[0-9]+\.[0-9]" 6 | 7 | help_text () { 8 | echo 9 | echo "Usage: deploy VERSION" 10 | echo 11 | } 12 | 13 | # check for required version to deploy 14 | if [ -z ${1+x} ]; then 15 | help_text 16 | echo "Error: VERSION is required" 17 | exit 1 18 | fi 19 | 20 | if [[ "$1" =~ ^${version_regex}$ ]]; then 21 | version="${1}" 22 | git_tag="v${version}" 23 | else 24 | help_text 25 | echo "Error: VERSION must be a valid semantic version (major.minor.patch)" 26 | exit 1 27 | fi 28 | 29 | # let's get some permission before making changes 30 | echo 31 | echo "The following changes are about to be made:" 32 | echo " - the development branch will be checked out" 33 | echo " - a new release branch for ${version} will be created at release-${version}" 34 | echo " - the version will be updated to ${version} in openapi.yaml" 35 | echo " - these changes will be commited and tagged ${git_tag}" 36 | echo 37 | read -p "Do you want to continue? " -n 1 -r 38 | echo 39 | 40 | if [[ ! $REPLY =~ ^[Yy]$ ]]; then 41 | exit 1 42 | fi 43 | 44 | # if we have made it this far, we are ready to make changes 45 | echo "Deploying version ${version}" 46 | 47 | echo "Checking out development branch" 48 | git checkout development 49 | 50 | # ensure no local changes to openapi.yaml 51 | git diff-index --quiet HEAD -- openapi.yaml 52 | 53 | exit_status=$? 54 | if [ $exit_status -ne 0 ]; then 55 | echo 56 | echo "Error: Local changes have been made to openapi.yaml." 57 | echo " Please commit those changes before proceeding." 58 | exit 1 59 | fi 60 | 61 | echo "Creating a release branch release-${version}" 62 | git checkout -b "release-${version}" 63 | 64 | echo "Updating openapi.yaml with the new version number" 65 | sed -E -i.bak "s|version: ${version_regex}|version: ${version}|" openapi.yaml \ 66 | && rm openapi.yaml.bak 67 | 68 | echo "Committing the version bump" 69 | git add openapi.yaml 70 | git commit -m "Bump version to ${version}" 71 | 72 | echo "Tagging the version commit with the version number" 73 | git tag "${git_tag}" 74 | 75 | echo "Running some final checks" 76 | echo 77 | 78 | exit_status=0 79 | 80 | if grep -Fxq " version: ${version}" openapi.yaml; then 81 | echo "OK - version ${version} is present in openapi.yaml" 82 | else 83 | echo "ERROR - version ${version} is not present in openapi.yaml" 84 | exit_status=1 85 | fi 86 | 87 | if git tag | grep -Fxq "${git_tag}"; then 88 | echo "OK - ${git_tag} is present in git tags" 89 | else 90 | echo "ERROR - ${git_tag} is not present in git tags" 91 | exit_status=1 92 | fi 93 | 94 | if [ $exit_status -ne 0 ]; then 95 | echo 96 | echo "Please resolve the ERRORs above." 97 | exit 1 98 | else 99 | echo 100 | echo "Release process is complete." 101 | echo 102 | echo "Once confirmed changes are verified, you can:" 103 | echo " git push release-${version}" 104 | echo " git push ${git_tag}" 105 | fi 106 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/linode/linode-api-docs/v4 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Usage: 3 | # ./bin/version 4 | # Prints the current version 5 | # ./bin/version minor 6 | # Tags a minor version bump 7 | # ./bin/version major 8 | # Tags a major version bump 9 | # ./bin/version changelog [-d distribution] 10 | # Prints a Debian changelog 11 | 12 | import subprocess 13 | import sys 14 | import os 15 | import re 16 | 17 | def get_version(ref="HEAD"): 18 | describe = call('git describe {}'.format(ref)) 19 | branch = call('git rev-parse --abbrev-ref HEAD') 20 | 21 | describe = describe.replace("-", ".").split(".") 22 | parts = [0, 0, 0, branch] 23 | 24 | l = len(describe) 25 | for i in range(3): 26 | if l > i: 27 | parts[i] = int(describe[i]) 28 | 29 | return tuple(parts) 30 | 31 | 32 | template = """{} ({}-1) {}; urgency=low 33 | 34 | * {} 35 | 36 | -- {} <{}> {} 37 | """ 38 | 39 | 40 | def call(cmd): 41 | _, output = subprocess.getstatusoutput(cmd) 42 | return output 43 | 44 | 45 | def gen_deb_changelog(distribution="", branchname=None): 46 | project = "apinext" 47 | 48 | git_cmd="git log -5 --pretty=format:%{}" 49 | 50 | commits = call(git_cmd.format("H")).split("\n") 51 | authors = call(git_cmd.format("aN")).split("\n") 52 | author_emails = call(git_cmd.format("aE")).split("\n") 53 | subjects = call(git_cmd.format("s")).split("\n") 54 | dates = call(git_cmd.format("aD")).split("\n") 55 | for commit, author, email, subject, date in zip(commits, authors, author_emails, subjects, dates): 56 | major, minor, patch, branch = get_version(commit) 57 | if not (major or minor or patch): 58 | version = "{}.{}.{}+git{}".format(major, minor, patch, commit) 59 | else: 60 | version = "{}.{}.{}{}".format(major, minor, patch, 61 | '' if branchname == 'master' 62 | else "~dev" if branchname == 'development' 63 | else "~testing" if re.findall('^release\/\d+\.\d+$', branchname) 64 | else '~PR' if branchname 65 | else '') 66 | if not len(distribution): 67 | distribution = "stable" if major >= 1 else "unstable" 68 | print(template.format(project, version, distribution, subject, author, email, date)) 69 | 70 | 71 | major, minor, patch, branch = get_version() 72 | 73 | if len(sys.argv) == 1: 74 | print("{}.{}.{}".format(major, minor, patch)) 75 | else: 76 | if sys.argv[1] == "branch": 77 | if len(sys.argv) == 2 or sys.argv[2] == "master": 78 | print("{}.{}.{}".format(major, minor, patch)) 79 | elif sys.argv[2] == "development": 80 | print("{}.{}.{}~dev".format(major, minor, patch)) 81 | elif re.findall('^release\/\d+\.\d+$', sys.argv[2]): 82 | print("{}.{}.{}~testing".format(major, minor, patch)) 83 | elif sys.argv[1] == "minor": 84 | ver = "{}.{}".format(major, minor + 1) 85 | call("git tag -a {} -m {}".format(ver, ver)) 86 | print("Created tag {}".format(ver)) 87 | elif sys.argv[1] == "major": 88 | ver = "{}.{}".format(major + 1, 0) 89 | call("git tag -a {} -m {}".format(ver, ver)) 90 | print("Created tag {}".format(ver)) 91 | elif sys.argv[1] == "changelog": 92 | if len(sys.argv)>3 and sys.argv[2] == "-d": 93 | distribution=sys.argv[3] 94 | else: 95 | distribution="" 96 | gen_deb_changelog(distribution, sys.argv[4] if len(sys.argv) > 4 else None) 97 | --------------------------------------------------------------------------------