-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for Equinix Metal (#5)
This adds support for Equinix Metal by replicating the existing spec patching and code generation processes from [`metal-python`](https://github.com/equinix-labs/metal-python). This ensures a smooth upgrade path for adopting `equinix-sdk-python` and gaining access to other services supported by this SDK, and unblocks packethost/packet-python#136. The code added here does not align with Equinix or OpenAPI standards and is subject to change. In particular, handling of additional properties does not follow OpenAPI rules and must be fixed in a future release.
- Loading branch information
Showing
1,296 changed files
with
198,588 additions
and
4 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file | ||
# | ||
* @equinix/governor-devrel-engineering | ||
|
||
*fabricv* @equinix/governor-digin-fabric | ||
*fabricv* @equinix/governor-digin-fabric | ||
*metalv* @equinix/governor-metal-client-interfaces |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
on: | ||
pull_request_target: | ||
paths: | ||
- 'config/**' | ||
- 'equinix_metal/**' | ||
- 'templates/**' | ||
- metal_openapi.fixed.yaml | ||
- 'oas3.stitched/**' | ||
- 'oas3.fetched/**' | ||
workflow_dispatch: | ||
|
||
permissions: | ||
pull-requests: read | ||
contents: read | ||
|
||
jobs: | ||
authorize: | ||
environment: | ||
${{ github.event_name == 'pull_request_target' && | ||
github.event.pull_request.head.repo.full_name != github.repository && | ||
'external' || 'internal' }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- run: true | ||
|
||
integration-test-pr: | ||
needs: authorize | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: update packages | ||
run: sudo apt-get update -y | ||
|
||
- name: install make | ||
run: sudo apt-get install -y build-essential | ||
|
||
- name: setup python 3 | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.10' | ||
|
||
- name: checkout Python SDK, this PR | ||
uses: actions/checkout@v4 | ||
with: | ||
ref: ${{ github.event.pull_request.head.sha || github.ref }} | ||
|
||
- name: checkout Ansible collection | ||
uses: actions/checkout@v4 | ||
with: | ||
repository: equinix-labs/ansible-collection-equinix | ||
path: .ansible/collections/ansible_collections/equinix/cloud | ||
ref: main | ||
|
||
- name: install dependencies of ansible collection | ||
run: pip3 install -r requirements-dev.txt -r requirements.txt | ||
working-directory: .ansible/collections/ansible_collections/equinix/cloud | ||
|
||
- name: install cloned Python SDK | ||
run: python3 -m pip install ./equinix_metal | ||
|
||
|
||
- name: replace existing keys | ||
run: rm -rf ~/.ansible/test && mkdir -p ~/.ansible/test && ssh-keygen -m PEM -q -t rsa -N '' -f ~/.ansible/test/id_rsa | ||
working-directory: .ansible/collections/ansible_collections/equinix/cloud | ||
|
||
- name: run tests in ansible collection directory | ||
run: make testall | ||
working-directory: .ansible/collections/ansible_collections/equinix/cloud | ||
env: | ||
METAL_API_TOKEN: ${{ secrets.METAL_API_TOKEN }} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
name: Sync metalv1 API spec | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
sync: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.8 | ||
- name: Get current date | ||
id: date | ||
run: echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT" | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
- name: GitHub user | ||
run: | | ||
# https://api.github.com/users/github-actions[bot] | ||
git config user.name 'github-actions[bot]' | ||
git config user.email '41898282+github-actions[bot]@users.noreply.github.com' | ||
- name: Fetch latest spec | ||
id: fetch | ||
run: | | ||
make -f Makefile.metalv1 fetch | ||
git add spec/services/metalv1 | ||
echo `git commit -m 'sync: fetch ${{ steps.date.outputs.date }} spec and apply patches'` | ||
- name: Apply spec patches | ||
id: patch | ||
if: ${{ always() && steps.fetch.conclusion == 'success' }} | ||
run: | | ||
make -f Makefile.metalv1 patch | ||
git add spec/services/metalv1 | ||
echo `git commit -m 'sync: patch spec with ${{ steps.date.outputs.date }} spec'` | ||
- name: Generate code | ||
id: generate | ||
if: ${{ always() && steps.patch.conclusion == 'success' }} | ||
run: | | ||
make -f Makefile.metalv1 generate | ||
git add services/metalv1 | ||
echo `git commit -m 'sync: generate client with ${{ steps.date.outputs.date }} spec'` | ||
- name: Create Pull Request | ||
id: cpr | ||
uses: peter-evans/create-pull-request@v6 | ||
if: ${{ always() && steps.fetch.conclusion == 'success' }} | ||
with: | ||
branch: sync/gh | ||
branch-suffix: timestamp | ||
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | ||
commit-message: "sync: uncommitted changes detected when opening PR" | ||
title: "feat: API Sync by GitHub Action for @${{ github.event.sender.login }}" | ||
body: | | ||
This API Sync PR was triggered by @${{ github.event.sender.login }} through [GitHub Actions workflow_displatch](https://github.com/equinix/equinix-sdk-python/actions?query=event%3Aworkflow_dispatch) | ||
on ${{ steps.date.outputs.date }}. | ||
* latest Swagger is fetched | ||
* patches have been applied | ||
* generated client has been updated | ||
delete-branch: true | ||
draft: ${{ steps.patch.conclusion == 'failure' || steps.generate.conclusion == 'failure' }} | ||
- name: Comment for failed patch | ||
uses: mshick/add-pr-comment@v2 | ||
if: ${{ always() && steps.patch.conclusion == 'failure' && steps.cpr.conclusion == 'success' }} | ||
with: | ||
issue: ${{ steps.cpr.outputs.pull-request-number }} | ||
message: Failed to patch latest spec. Someone with write access must fix this PR manually and then convert it from Draft status to Ready for Review. | ||
- name: Comment for failed generate | ||
uses: mshick/add-pr-comment@v2 | ||
if: ${{ always() && steps.generate.conclusion == 'failure' && steps.cpr.conclusion == 'success' }} | ||
with: | ||
issue: ${{ steps.cpr.outputs.pull-request-number }} | ||
message: Failed to generate code from latest patched spec. Someone with write access must fix this PR manually and then convert it from Draft status to Ready for Review. | ||
- name: Check outputs | ||
if: ${{ always() && steps.cpr.conclusion == 'success' }} | ||
run: | | ||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" | ||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
.PHONY: all pull fetch patch generate clean codegen mod docs move-other patch-post fmt test stage | ||
|
||
include Makefile | ||
|
||
PACKAGE_NAME=metalv1 | ||
SPEC_BASE_URL:=https://api.equinix.com/metal/v1/api-docs | ||
SPEC_ROOT_FILE:=openapi3.yaml | ||
|
||
CODE_DIR=equinix/services/${PACKAGE_NAME} | ||
TEMPLATE_DIR=${TEMPLATE_BASE_DIR}/${PACKAGE_NAME} | ||
SPEC_FETCHED_DIR=${SPEC_BASE_DIR}/${PACKAGE_NAME}/oas3.fetched | ||
SPEC_PATCH_DIR=${SPEC_BASE_DIR}/${PACKAGE_NAME}/patches | ||
SPEC_PATCHED_DIR=${SPEC_BASE_DIR}/${PACKAGE_NAME}/oas3.patched | ||
SPEC_STITCHED_DIR=${SPEC_BASE_DIR}/${PACKAGE_NAME}/oas3.stitched | ||
all: pull fetch patch generate stage | ||
|
||
generate: clean codegen patch-post fmt test | ||
|
||
pull: | ||
${CRI} pull ${OPENAPI_IMAGE} | ||
|
||
fetch: | ||
${SPEC_FETCHER} ${SPEC_BASE_URL} ${SPEC_FETCHED_DIR} ${SPEC_ROOT_FILE} | ||
|
||
patch: | ||
rm -rf ${SPEC_PATCHED_DIR} | ||
cp -r ${SPEC_FETCHED_DIR} ${SPEC_PATCHED_DIR} | ||
|
||
# TODO: fetch the merged (single-file) spec | ||
# instead of merging it here | ||
${OPENAPI_GENERATOR} generate \ | ||
-i /local/${SPEC_PATCHED_DIR}/${SPEC_ROOT_FILE} \ | ||
-g openapi-yaml \ | ||
-p skipOperationExample=true -p outputFile=${SPEC_ROOT_FILE} \ | ||
-o /local/${SPEC_PATCHED_DIR} | ||
|
||
rm -rf ${SPEC_PATCHED_DIR}/.openapi-generator* \ | ||
${SPEC_PATCHED_DIR}/README.md \ | ||
${SPEC_PATCHED_DIR}/components \ | ||
${SPEC_PATCHED_DIR}/paths | ||
|
||
for diff in $(shell set -x; find ${SPEC_PATCH_DIR} -name '*.patch' | sort -n); do \ | ||
patch --no-backup-if-mismatch -N -t -p1 -i $$diff; \ | ||
done | ||
|
||
script/patch_metal_spec.py ${SPEC_PATCHED_DIR}/${SPEC_ROOT_FILE} ${SPEC_PATCHED_DIR}/${SPEC_ROOT_FILE} | ||
|
||
patch-post: | ||
# patch is idempotent, always starting with the generated files | ||
for diff in $(shell find patches/post -name \*.patch | sort -n); do \ | ||
patch --no-backup-if-mismatch -N -t -p1 -i $$diff; \ | ||
done | ||
|
||
clean: | ||
rm -rf $(CODE_DIR) | ||
|
||
codegen: | ||
${OPENAPI_GENERATOR} generate -g python \ | ||
--package-name equinix.services.${PACKAGE_NAME} \ | ||
--http-user-agent "${USER_AGENT}" \ | ||
-p packageVersion=${PACKAGE_VERSION} \ | ||
--git-user-id ${GIT_ORG} \ | ||
--git-repo-id ${GIT_REPO} \ | ||
`# TODO: re-enable the config file option so that generated code follows OpenAPI standards; this is only disabled to provide an upgrade path for metal-python` \ | ||
`# -c /local/config/openapi-generator.json` \ | ||
`# TODO: remove this when the config file is re-enabled` \ | ||
-p generateSourceCodeOnly=true \ | ||
-t /local/${TEMPLATE_DIR} \ | ||
-o /local/ \ | ||
-i /local/${SPEC_PATCHED_DIR}/${SPEC_ROOT_FILE} | ||
|
||
validate: | ||
${OPENAPI_GENERATOR} validate \ | ||
--recommend \ | ||
-i /local/${SPEC_PATCHED_DIR}/${SPEC_ROOT_FILE} |
Oops, something went wrong.