Compare commits

..

601 commits

Author SHA1 Message Date
6608d0aa8c
refactor(params): ♻️ Simplify ForgeURL logic by removing redundant switch case
Some checks failed
CodeQL / Analyze (push) Failing after 2s
Go Tests / Linters (push) Successful in 3m26s
Go Tests / go-tests (push) Successful in 6m41s
Streamlines the ForgeURL method by removing an unnecessary nested switch case
on ForgeType, consolidating the logic to rely solely on EntityType. This change
reduces complexity and improves code readability without altering functionality.
2025-08-27 16:04:56 +02:00
Gabriel
29f2e2a2b9
Merge pull request #499 from gabriel-samfira/better-cli-log-formatting
Make the debug-log command more useful
2025-08-27 16:27:33 +03:00
Gabriel Adrian Samfira
0faeee703d Make the debug-log command more useful
The debug-log command now supports log level filtering and attribute
filtering. The log level filtering will only be able to set the minimum
log level as low as the server is configured to stream. If the server has
its log level set as INFO, then setting the log level in the CLI to DEBUG
will have no effect.

But anything above what the server sends, is within the control of the client
to filter. This is all done client side.

Attribute filters are useful if you need to watch the logs for a particular
worker, entity, etc.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-27 13:21:56 +00:00
Gabriel
e3a9fe7026
Merge pull request #498 from gabriel-samfira/preload-more-info
Preload more info for entity pools
2025-08-27 12:27:04 +03:00
Gabriel Adrian Samfira
9ef4566cae Preload more info for entity pools
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-27 09:14:45 +00:00
Gabriel
e79a5c1d50
Merge pull request #496 from cloudbase/dependabot/go_modules/github.com/stretchr/testify-1.11.0
Bump github.com/stretchr/testify from 1.10.0 to 1.11.0
2025-08-25 19:35:17 +03:00
Gabriel
89fecd9dcd
Merge pull request #497 from gabriel-samfira/fix-double-pool
Fix double creation of pools
2025-08-25 19:18:07 +03:00
Gabriel Adrian Samfira
6fee10c737 Fix double creation of pools
This change fixes the creation of pools though the UI. Both the modal and
the page were sending a request to create the pool, leading to double pool.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-25 16:12:01 +00:00
dependabot[bot]
642b3bbf92
Bump github.com/stretchr/testify from 1.10.0 to 1.11.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-25 11:54:27 +00:00
Gabriel
1fceec374d
Merge pull request #495 from gabriel-samfira/caching-and-fixes
Attempt to use the scalset API and caching
2025-08-25 01:45:46 +03:00
Gabriel Adrian Samfira
d05df36868 Attempt to use the scalset API and caching
On github, attempt to use the scaleset API to list all runners without
pagination. This will avoid missing runners and accidentally removing them.

Fall back to paginated API if we can't use the scaleset API.

Add ability to retrieve all instances from cache, for an entity.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-24 22:36:44 +00:00
Gabriel
5c703f310b
Merge pull request #494 from gabriel-samfira/small-fixes
Small fixes
2025-08-24 11:53:21 +03:00
Gabriel Adrian Samfira
86a0b0cf4f Small fixes
* Shut down the web server first to prevent errors caused by clients trying
to use functionality that has already been shut down, causing errors and
potentially delaying the shutdown process.
* remove write timeout from the websocket Write() function.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-24 08:35:17 +00:00
Gabriel
5a26614acf
Merge pull request #493 from gabriel-samfira/ensure-scale-set
Ensure scale set exists
2025-08-23 22:12:30 +03:00
Gabriel Adrian Samfira
39003f006a Ensure scale set exists
Github will remove inactive scale sets after 7 days. This change
ensures the scale set exists in github before spinning up the listener.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-23 18:55:08 +00:00
Gabriel
c48bb50f2a
Merge pull request #492 from gabriel-samfira/add-webui-tests
Add webui tests
2025-08-22 00:18:57 +03:00
Gabriel Adrian Samfira
54c6571ccd Update test workflow
Add steps to test the Web UI and to run go generate.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 21:00:27 +00:00
Gabriel Adrian Samfira
8d5c6b6738 Bump go version to 1.24.6 and run go generate
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 20:36:50 +00:00
Gabriel Adrian Samfira
48769587bb Add web UI tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 20:36:50 +00:00
Gabriel
9aa2e297b9
Merge pull request #491 from igrikus/main
fix(jobs): Correctly handle workflow job IDs from webhooks
2025-08-21 22:04:35 +03:00
Gabriel Adrian Samfira
4341b4869c Fix erroneous calls to Job related functions
Some functions were left behind when we added WorkflowJobID.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-21 18:57:42 +00:00
igrikus
8bda81d6cc fix(jobs): Correctly handle workflow job IDs from webhooks 2025-08-21 14:54:38 +02:00
Gabriel
004c03962f
Merge pull request #488 from gabriel-samfira/remove-deprecated
Replace ${base} with resolve()
2025-08-18 16:09:32 +03:00
Gabriel Adrian Samfira
69a2c509a7 Replace ${base} with resolve()
This removes some deprecated code.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-18 13:08:58 +00:00
Gabriel
b8ff6d9e14
Merge pull request #487 from gabriel-samfira/small-fixes
Fix href for entities
2025-08-18 15:03:24 +03:00
Gabriel Adrian Samfira
9028ef64b1 Fix href for entities
The URL from scale sets and pools to the entity to which they belong
was not being properly resolved.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-18 12:02:08 +00:00
Gabriel
eeed5ae508
Merge pull request #486 from gabriel-samfira/small-fixes
Fix endpoint type name and update cookie
2025-08-18 01:28:47 +03:00
Gabriel Adrian Samfira
04d1042a4c Fix endpoint type name and update cookie
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-17 22:27:17 +00:00
Gabriel
102c430e1d
Merge pull request #485 from gabriel-samfira/ui-fixes
Slightly better error handling
2025-08-17 10:42:33 +03:00
Gabriel Adrian Samfira
7f647941f6 Slightly better error handling
Extract error details we get from the API when status code > 2xx.
Also, use toast messages to display the error, properly close delete
modals and prevent full page display of error messages.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-17 07:34:40 +00:00
Gabriel
8cf0b0a56e
Merge pull request #484 from gabriel-samfira/remove-all-flag-scalesets
Remove the --all flag for scalesets
2025-08-17 02:20:16 +03:00
Gabriel Adrian Samfira
f805123a85 Remove the --all flag for scalesets
Display all scalesets by default, similar to runners and pools.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 23:13:47 +00:00
Gabriel
6b49c21206
Merge pull request #483 from gabriel-samfira/fix-inconsistency
Allow referencing runners by ID
2025-08-17 02:08:02 +03:00
Gabriel Adrian Samfira
31ad45eeb6 Allow referencing runners by ID
Although runner names are unique, we still have an ID on the model
which is used as a primary key. We should allow using that ID to
reference a runner in the API.

This change allows users to specify ID or runner name.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 23:00:55 +00:00
Gabriel
b4113048bb
Merge pull request #482 from gabriel-samfira/switch-to-fmt-errorf
Switch to fmt.Errorf
2025-08-17 01:28:22 +03:00
Gabriel Adrian Samfira
118319c7c1 Switch to fmt.Errorf
Replace all instances of errors.Wrap() with fmt.Errorf.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 22:19:05 +00:00
Gabriel
10dcbec954
Merge pull request #481 from cloudbase/dependabot/npm_and_yarn/webapp/npm_and_yarn-2ea0fb2c37
Bump the npm_and_yarn group across 1 directory with 2 updates
2025-08-16 14:31:17 +03:00
dependabot[bot]
b58bf4c895
Bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 2 updates in the /webapp directory: [tmp](https://github.com/raszi/node-tmp) and [@openapitools/openapi-generator-cli](https://github.com/OpenAPITools/openapi-generator-cli).


Removes `tmp`

Updates `@openapitools/openapi-generator-cli` from 2.21.4 to 2.22.0
- [Release notes](https://github.com/OpenAPITools/openapi-generator-cli/releases)
- [Changelog](https://github.com/OpenAPITools/openapi-generator-cli/blob/master/.releaserc)
- [Commits](https://github.com/OpenAPITools/openapi-generator-cli/compare/v2.21.4...v2.22.0)

---
updated-dependencies:
- dependency-name: tmp
  dependency-version: 
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: "@openapitools/openapi-generator-cli"
  dependency-version: 2.22.0
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-16 10:25:06 +00:00
Gabriel
8cc96dbcd1
Merge pull request #479 from gabriel-samfira/spa-webapp
Spa webapp
2025-08-16 13:23:42 +03:00
Gabriel Adrian Samfira
eec158b32c Add SPA UI for GARM
This change adds a single page application front-end to GARM. It uses
a generated REST client, built from the swagger definitions, the websocket
interface for live updates of entities and eager loading of everything
except runners, as users may have many runners and we don't want to load
hundreds of runners in memory.

Proper pagination should be implemented in the API, in future commits,
to avoid loading lots of elements for no reason.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-16 09:09:13 +00:00
Gabriel Adrian Samfira
a811d129d0 Update .gitignore
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel Adrian Samfira
98a769b8d1 Allow cookie login to API endpoints
This change considers cookies as a source for the JWT token.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel Adrian Samfira
5a6ac12118 Fix for gitea tools and scale set cleanup
Filter out gitea tools to only consider archived downloads. This
should help in situations where bandwidth is more important than
CPU time used to unarchive the tools.

Also a drive by fix for scale sets cleanup.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel Adrian Samfira
325bca4af3 Add swagger annotations and updates
Add swagger annotations to models to allow generating a full swagger
definition. This will help generate clients in other languages if needed.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel Adrian Samfira
b2dee1d844 Preload missing resources
There are some inconsistencies in the way the API returns some
values for pools and scale sets. This is due to not preloading
the appropriate relations.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-12 12:48:48 +00:00
Gabriel
9f2764f614
Merge pull request #478 from cloudbase/dependabot/go_modules/github.com/go-openapi/errors-0.22.2
Bump github.com/go-openapi/errors from 0.22.1 to 0.22.2
2025-08-11 21:20:33 +03:00
dependabot[bot]
37eba0fed9
Bump github.com/go-openapi/errors from 0.22.1 to 0.22.2
Bumps [github.com/go-openapi/errors](https://github.com/go-openapi/errors) from 0.22.1 to 0.22.2.
- [Commits](https://github.com/go-openapi/errors/compare/v0.22.1...v0.22.2)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/errors
  dependency-version: 0.22.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 10:34:11 +00:00
Gabriel
389a8538af
Merge pull request #476 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.41.0
Bump golang.org/x/crypto from 0.40.0 to 0.41.0
2025-08-08 12:54:56 +03:00
dependabot[bot]
f24a22d537
Bump golang.org/x/crypto from 0.40.0 to 0.41.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.40.0 to 0.41.0.
- [Commits](https://github.com/golang/crypto/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 09:47:38 +00:00
Gabriel
dfa9848999
Merge pull request #477 from cloudbase/dependabot/go_modules/golang.org/x/mod-0.27.0
Bump golang.org/x/mod from 0.26.0 to 0.27.0
2025-08-08 12:46:12 +03:00
dependabot[bot]
3f51046279
Bump golang.org/x/mod from 0.26.0 to 0.27.0
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.26.0 to 0.27.0.
- [Commits](https://github.com/golang/mod/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 06:49:58 +00:00
Gabriel
256521ac38
Merge pull request #475 from cloudbase/dependabot/go_modules/github.com/cloudbase/garm-provider-common-0.1.7
Bump github.com/cloudbase/garm-provider-common from 0.1.6 to 0.1.7
2025-08-07 15:34:27 +03:00
dependabot[bot]
e2169865a1
Bump github.com/cloudbase/garm-provider-common from 0.1.6 to 0.1.7
Bumps [github.com/cloudbase/garm-provider-common](https://github.com/cloudbase/garm-provider-common) from 0.1.6 to 0.1.7.
- [Release notes](https://github.com/cloudbase/garm-provider-common/releases)
- [Commits](https://github.com/cloudbase/garm-provider-common/compare/v0.1.6...v0.1.7)

---
updated-dependencies:
- dependency-name: github.com/cloudbase/garm-provider-common
  dependency-version: 0.1.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-07 07:05:40 +00:00
Gabriel
fd9a4d544a
Merge pull request #474 from gabriel-samfira/fix-image-tag
Get the image tag from supplied ref
2025-08-07 00:13:51 +03:00
Gabriel Adrian Samfira
20a16d923c
Get the image tag from supplied ref
We need to pass the ref used in the workflow. If we supply a tag,
we should just get that same tag. If we supply a branch, we should
get the latest release from that branch.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-07 00:12:35 +03:00
Gabriel
212f6fff42
Merge pull request #473 from gabriel-samfira/fix-build-image
Use the Dockerfile from the main branch
2025-08-06 23:11:29 +03:00
Gabriel Adrian Samfira
2ee2fca8ae
Use the Dockerfile from the main branch
There is no way to change the Dockerfile in a tag. We need to
use the Dockerfile in the main branch. So even if we're buildin
the image for a stable version, we need to check out the main branch.

The Dockerfile will take care of checking out the proper tags.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-06 23:09:01 +03:00
Gabriel Adrian Samfira
5915107446
WiP
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-08-06 23:03:45 +03:00
Gabriel
e43acd5b65
Merge pull request #472 from cloudbase/dependabot/go_modules/github.com/prometheus/client_golang-1.23.0
Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.0
2025-08-01 10:10:35 +03:00
dependabot[bot]
f85fe3d63f
Bump github.com/prometheus/client_golang from 1.22.0 to 1.23.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.22.0 to 1.23.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/v1.23.0/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.22.0...v1.23.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 06:26:29 +00:00
Gabriel
8082e1a30e
Merge pull request #456 from chickenkiller/feat/refactor-builds
Refactor CI/CD builds
2025-07-31 10:58:16 +03:00
Gabriel
daf2a13e48
Merge pull request #471 from cloudbase/dependabot/go_modules/github.com/golang-jwt/jwt/v5-5.3.0
Bump github.com/golang-jwt/jwt/v5 from 5.2.3 to 5.3.0
2025-07-31 10:14:59 +03:00
dependabot[bot]
4ad7d8e856
Bump github.com/golang-jwt/jwt/v5 from 5.2.3 to 5.3.0
Bumps [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) from 5.2.3 to 5.3.0.
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.2.3...v5.3.0)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-31 07:04:47 +00:00
Lionel ORRY
22f655f48d fixes after testing 2025-07-31 08:42:16 +02:00
Lionel ORRY
158b35db06 simplify workflows 2025-07-30 14:35:01 +02:00
Lionel ORRY
eb07ed3774 remove obsolete tech debt 2025-07-30 12:12:03 +02:00
Lionel ORRY
0f4f98dd03 put a better git version in providers 2025-07-30 12:12:02 +02:00
Lionel ORRY
f6f22cb686 small fixes 2025-07-30 12:09:34 +02:00
Lionel ORRY
af1c090db5 transfer providers branch computation inside Dockerfile 2025-07-30 12:09:32 +02:00
Lionel ORRY
be3026e87c fix branch names 2025-07-30 12:04:02 +02:00
Lionel ORRY
5152bab1b8 fix branch names 2025-07-30 12:04:02 +02:00
Lionel ORRY
3687c7fea4 activate release/v2 nightly build 2025-07-30 12:04:02 +02:00
Lionel ORRY
1e8d0d79a6 improvements after review comments 2025-07-30 12:04:02 +02:00
Lionel ORRY
97ef92706b refactor workflows to enable multiple docker images 2025-07-30 12:04:00 +02:00
Gabriel
53cdfd70a1
Merge pull request #470 from cloudbase/dependabot/go_modules/github.com/jedib0t/go-pretty/v6-6.6.8
Bump github.com/jedib0t/go-pretty/v6 from 6.6.7 to 6.6.8
2025-07-28 12:30:47 +03:00
dependabot[bot]
7817d20516
Bump github.com/jedib0t/go-pretty/v6 from 6.6.7 to 6.6.8
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.6.7 to 6.6.8.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.6.7...v6.6.8)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-version: 6.6.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 08:04:00 +00:00
Gabriel
daadad682b
Merge pull request #468 from cloudbase/dependabot/go_modules/gorm.io/gorm-1.30.1
Bump gorm.io/gorm from 1.30.0 to 1.30.1
2025-07-24 09:55:44 +03:00
dependabot[bot]
f4892be193
Bump gorm.io/gorm from 1.30.0 to 1.30.1
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.30.0 to 1.30.1.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/compare/v1.30.0...v1.30.1)

---
updated-dependencies:
- dependency-name: gorm.io/gorm
  dependency-version: 1.30.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-24 06:47:05 +00:00
Gabriel
e687565671
Merge pull request #467 from cloudbase/dependabot/go_modules/github.com/cloudbase/garm-provider-common-0.1.6
Bump github.com/cloudbase/garm-provider-common from 0.1.5 to 0.1.6
2025-07-21 11:45:24 +03:00
dependabot[bot]
567c465ad7
Bump github.com/cloudbase/garm-provider-common from 0.1.5 to 0.1.6
Bumps [github.com/cloudbase/garm-provider-common](https://github.com/cloudbase/garm-provider-common) from 0.1.5 to 0.1.6.
- [Release notes](https://github.com/cloudbase/garm-provider-common/releases)
- [Commits](https://github.com/cloudbase/garm-provider-common/compare/v0.1.5...v0.1.6)

---
updated-dependencies:
- dependency-name: github.com/cloudbase/garm-provider-common
  dependency-version: 0.1.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-21 07:58:08 +00:00
Gabriel
f1fed3c462
Merge pull request #466 from gabriel-samfira/update-docs-and-defaults
Update docs and deprecate the --all flag
2025-07-20 23:38:50 +03:00
Gabriel Adrian Samfira
80735ac2eb Update docs and deprecate the --all flag
Update the docs to reflect the latest stable version and deprecate the
--all flag for runner list and pool list.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-20 20:31:56 +00:00
Gabriel
bb45324dcd
Merge pull request #459 from gabriel-samfira/account-for-job-id
Handle new jobID for scale sets
2025-07-18 11:39:06 +03:00
Gabriel Adrian Samfira
a984782fd7 Handle new jobID for scale sets
There seems to be a change in the scale set message. It now includes
a jobID and sets the runner request ID to 0. This change adds separate
job ID fields for workflow jobs and scaleset jobs.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-18 08:20:50 +00:00
Gabriel
d26973da2a
Merge pull request #458 from gabriel-samfira/fix-scaleset-param
Fix scale set param
2025-07-17 20:06:14 +03:00
Gabriel Adrian Samfira
69779a0a7d Fix scale set param
Do not look for a name when composing the scale set. Preload may not
have been called on an entity, but we still have the ID, which is the
only thing needed when GetEntity() is called.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-17 17:01:20 +00:00
Gabriel
c95252547e
Merge pull request #454 from gabriel-samfira/fix-encoding
Handle query args
2025-07-16 17:52:02 +03:00
Gabriel
d17b168b4e
Merge pull request #453 from cloudbase/dependabot/go_modules/github.com/golang-jwt/jwt/v5-5.2.3
Bump github.com/golang-jwt/jwt/v5 from 5.2.2 to 5.2.3
2025-07-16 10:36:26 +03:00
dependabot[bot]
a46c474640
Bump github.com/golang-jwt/jwt/v5 from 5.2.2 to 5.2.3
Bumps [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.2.2...v5.2.3)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-version: 5.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-16 06:41:38 +00:00
Gabriel Adrian Samfira
65d6d1ae87 Handle query args
Merge any query args from both the GH url and the supplied URL.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-16 06:39:46 +00:00
Gabriel
78547fefaa
Merge pull request #450 from cloudbase/dependabot/go_modules/golang.org/x/mod-0.26.0
Bump golang.org/x/mod from 0.25.0 to 0.26.0
2025-07-11 14:48:26 +03:00
dependabot[bot]
0cc51e48ef
Bump golang.org/x/mod from 0.25.0 to 0.26.0
---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 09:34:59 +00:00
Gabriel
86b8ac9e94
Merge pull request #451 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.40.0
Bump golang.org/x/crypto from 0.39.0 to 0.40.0
2025-07-11 12:33:37 +03:00
dependabot[bot]
f9b1b26f80
Bump golang.org/x/crypto from 0.39.0 to 0.40.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.39.0 to 0.40.0.
- [Commits](https://github.com/golang/crypto/compare/v0.39.0...v0.40.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 06:28:17 +00:00
Gabriel
19e025c2be
Merge pull request #448 from gabriel-samfira/fix-sleep
Fix sleepWithCancel and ensure closed channel
2025-07-07 08:02:32 +03:00
Gabriel Adrian Samfira
b23bca73bc Fix sleepWithCancel and ensure closed channel
* time.NewTicker will panic if the duration is 0. Make it return
early if duration is 0.
* Return a pre-closed channel in Wait() instead of nil. Ensures receiver
will not block forever.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-07 04:54:10 +00:00
Gabriel
20d4e68fd4
Merge pull request #447 from gabriel-samfira/fix-makefile
Use the -v flag on podman only
2025-07-07 00:26:46 +03:00
Gabriel Adrian Samfira
6ae3b25b4d Use the -v flag on podman only
Docker does not support the --volume flag at build time. This needs
to be done in the Dockerfile directly on the RUN stanza. Will update
in a future PR, until then, just set the flag for podman.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-06 21:17:31 +00:00
Gabriel
e14f3858ef
Merge pull request #446 from gabriel-samfira/fix-url-composition
Use JoinPath() and relative paths
2025-07-06 22:56:35 +03:00
Gabriel Adrian Samfira
18902f884a Use JoinPath() and relative paths
Use JoinPath() in newActionsRequest() and make sure we pass relative
paths to it. This should fix scale sets on GHES.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-07-06 19:22:43 +00:00
Gabriel
379c39095e
Merge pull request #444 from chickenkiller/fix-podman
improve usability of podman in Makefile
2025-07-02 15:15:16 +03:00
Lionel ORRY
3853f8bd94 improve usability of podman in Makefile 2025-07-02 14:04:41 +02:00
Gabriel
9f5cf64542
Merge pull request #441 from cloudbase/dependabot/go_modules/gorm.io/datatypes-1.2.6
Bump gorm.io/datatypes from 1.2.5 to 1.2.6
2025-07-01 12:50:30 +03:00
dependabot[bot]
7c8241579d
Bump gorm.io/datatypes from 1.2.5 to 1.2.6
Bumps [gorm.io/datatypes](https://github.com/go-gorm/datatypes) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/go-gorm/datatypes/releases)
- [Commits](https://github.com/go-gorm/datatypes/compare/v1.2.5...v1.2.6)

---
updated-dependencies:
- dependency-name: gorm.io/datatypes
  dependency-version: 1.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 09:02:05 +00:00
Gabriel
25e7befa08
Merge pull request #440 from gabriel-samfira/forward-port-439
Set http transport config
2025-06-27 11:27:48 +03:00
Gabriel Adrian Samfira
529ce8b7a8 Set http transport config
This change sets the github client http transport options to mirror those
of the default transport from Go, with the addition of the TLSClientConfig.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-27 08:19:45 +00:00
Gabriel
42839917f3
Merge pull request #437 from gabriel-samfira/several-fixes
Some cleanup
2025-06-21 20:54:03 +03:00
Gabriel Adrian Samfira
1ec99e8695 Some cleanup
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-21 17:31:26 +00:00
Gabriel
6c104b6ece
Merge pull request #432 from gabriel-samfira/use-friendly-names
Allow usage of friendly names in most commands
2025-06-21 20:15:14 +03:00
Gabriel Adrian Samfira
808af82e0d Add endpoint option to all relevant commands
In case of ambiguity when using the name of a repo, org or enterprise,
an --endpoint flag can be used to uniquely identify an entity against
an endpoint.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-21 17:05:22 +00:00
Gabriel
7c2086bc64
Merge pull request #436 from cloudbase/dependabot/go_modules/github.com/cloudbase/garm-provider-common-0.1.5
Bump github.com/cloudbase/garm-provider-common from 0.1.5-0.20250417155201-8ef03502d06e to 0.1.5
2025-06-20 14:08:02 +03:00
dependabot[bot]
ed924e8034
Bump github.com/cloudbase/garm-provider-common
Bumps [github.com/cloudbase/garm-provider-common](https://github.com/cloudbase/garm-provider-common) from 0.1.5-0.20250417155201-8ef03502d06e to 0.1.5.
- [Release notes](https://github.com/cloudbase/garm-provider-common/releases)
- [Commits](https://github.com/cloudbase/garm-provider-common/commits/v0.1.5)

---
updated-dependencies:
- dependency-name: github.com/cloudbase/garm-provider-common
  dependency-version: 0.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-20 07:08:08 +00:00
Gabriel Adrian Samfira
e92b2c1111 Allow usage of friendly names in most commands
This change adds the ability to use the repo/org/enterprise names
instead of UUID in most garm-cli commands, at the expense of an extra
list API call, leveraging the recently added filter options.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-19 09:27:18 +00:00
Gabriel
43a2343828
Merge pull request #431 from gabriel-samfira/add-filter-option
Add a rudimentary filter option when listing entities
2025-06-19 00:34:56 +03:00
Gabriel Adrian Samfira
499fbde60c Add a rudimentary filter option when listing entities
This change adds the ability to filter the list of entities returned
by the API by entity owner, name or endpoint, depending on the entity
type.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-18 21:23:34 +00:00
Gabriel
2fd0e720e6
Merge pull request #430 from gabriel-samfira/update-deps
Update dependencies
2025-06-18 00:15:19 +03:00
Gabriel Adrian Samfira
d42160cab2 Update dependencies
This change updates all dependencies.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-06-17 21:09:05 +00:00
Gabriel
e3833e5e48
Merge pull request #429 from tormath1/tormath1/doc
doc/gitea: remove 'version'
2025-06-12 20:17:43 +03:00
Mathieu Tortuyaux
98fa085bc7
doc/gitea: remove 'version'
This field is deprecated:
```
$ docker compose version
Docker Compose version v2.36.2
...
WARN[0000] /home/core/docker-compose.yaml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
```

Signed-off-by: Mathieu Tortuyaux <mtortuyaux@microsoft.com>
2025-06-12 09:53:59 +02:00
Gabriel
d13ea92a54
Merge pull request #428 from tormath1/tormath1/linode
readme: add akamai/linode experimental external provider
2025-06-11 07:25:13 +03:00
Mathieu Tortuyaux
4c536f2584
readme: add Akamai/Linode external provider
The provider is quite new and awaits for feedback, let's mention the
"experimental" status.

Signed-off-by: Mathieu Tortuyaux <mtortuyaux@microsoft.com>
2025-06-10 17:59:29 +02:00
Mathieu Tortuyaux
043359936b
readme: sort external providers
Signed-off-by: Mathieu Tortuyaux <mtortuyaux@microsoft.com>
2025-06-10 17:58:11 +02:00
Gabriel
1c2f349d56
Merge pull request #413 from cloudbase/dependabot/go_modules/gorm.io/gorm-1.30.0
Bump gorm.io/gorm from 1.26.1 to 1.30.0
2025-05-29 21:38:15 +03:00
Gabriel
be86709bdf
Merge pull request #419 from gabriel-samfira/enable-tests-in-release
Trigger tests on release branches
2025-05-29 20:15:00 +03:00
Gabriel Adrian Samfira
48c4ea7d15 Trigger tests on release branches
This change triggers tests for PRs created against release/* branches.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-29 17:07:46 +00:00
Gabriel
c19bf2f9f8
Merge pull request #416 from ChristopherHX/optional-forge-type-for-gitea
Create Repo / Org make --forge-type optional
2025-05-29 20:04:51 +03:00
Christopher Homberger
efd725ea94 Create Repo / Org make --forge-type optional
* This makes gitea garm usage unnessary complex

Signed-off-by: Christopher Homberger <christopher.homberger@web.de>
2025-05-29 18:36:25 +02:00
dependabot[bot]
914f7fbd49
Bump gorm.io/gorm from 1.26.1 to 1.30.0
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.26.1 to 1.30.0.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/compare/v1.26.1...v1.30.0)

---
updated-dependencies:
- dependency-name: gorm.io/gorm
  dependency-version: 1.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 06:15:56 +00:00
Gabriel
18ef27bb91
Merge pull request #412 from gabriel-samfira/allow-deleting-default-ep
Make the default github endpoint mutable
2025-05-25 01:32:23 +03:00
Gabriel Adrian Samfira
87055f23da Make the default github endpoint mutable
This change allows users to remove the default github endpoint
if no credentials are set on it.

A new protection is added on URLs of any endpoint that prevents their
update if the endpoint has credentials set.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-24 22:26:01 +00:00
Gabriel
b5bd373061
Merge pull request #411 from gabriel-samfira/add-logo
Experiment with a logo
2025-05-24 23:35:06 +03:00
Gabriel Adrian Samfira
ae69e8c473 Experiment with a logo
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-24 20:13:05 +00:00
Gabriel
451e7c4556
Merge pull request #408 from gabriel-samfira/fix-add-entity-event
Fix AddInstanceEvent and expose events
2025-05-22 22:24:36 +03:00
Gabriel Adrian Samfira
9921a7bfc8 Fix AddInstanceEvent and expose events
* We were passing the wrong type to GORM for events
* We now expose entity events in the API and CLI

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-22 19:19:24 +00:00
Gabriel
ed8e11e244
Merge pull request #405 from gabriel-samfira/ensure-token
Ensure that admin token exists
2025-05-22 00:38:47 +03:00
Gabriel Adrian Samfira
7e576dc631 Ensure that admin token exists
Make sure that the admin info is populated when calling GenerateJitRunnerConfig.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-21 21:29:43 +00:00
Gabriel
d8cb1c5acd
Merge pull request #404 from gabriel-samfira/fix-cli
Avoid nil pointer dereference in CLI
2025-05-21 23:58:56 +03:00
Gabriel Adrian Samfira
9660b28019 Avoid nil pointer dereference in CLI
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-21 20:58:21 +00:00
Gabriel
f5c3363249
Merge pull request #403 from cloudbase/gabriel-samfira-patch-1
Update Dockerfile
2025-05-21 23:46:43 +03:00
Gabriel
4e157fc4cc
Update Dockerfile 2025-05-21 23:46:29 +03:00
Gabriel
ac0caa2ed9
Merge pull request #402 from gabriel-samfira/fix-parse-error
Fix potential nil pointer dereference
2025-05-21 22:50:44 +03:00
Gabriel Adrian Samfira
cfe707e522 Fix potential nil pointer dereference
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-21 19:45:23 +00:00
Gabriel
8c16ee92b3
Merge pull request #400 from kaspar030/patch-1
Fix some typos in scalesets.md
2025-05-21 17:45:25 +03:00
Kaspar Schleiser
8e8d7fd364
Fix some typos in scalesets.md 2025-05-21 16:39:22 +02:00
Gabriel
7646ff4429
Merge pull request #399 from cloudbase/gabriel-samfira-patch-1
Update gitea.md
2025-05-21 13:52:45 +03:00
Gabriel
93768a2796
Update gitea.md 2025-05-21 13:52:15 +03:00
Gabriel
65aa92f517
Merge pull request #398 from gabriel-samfira/add-docker-compose-example
Add examples for setting up GARM with Gitea
2025-05-21 13:28:48 +03:00
Gabriel Adrian Samfira
1c758d010a Add examples for setting up GARM with Gitea
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-21 10:27:59 +00:00
Gabriel
c85aea2d26
Merge pull request #396 from cloudbase/fix-schedule
Use default values for ref and push to project
2025-05-21 11:10:53 +03:00
Gabriel
f95bfee0d9
Merge pull request #397 from cloudbase/dependabot/go_modules/golang.org/x/mod-0.24.0
Bump golang.org/x/mod from 0.17.0 to 0.24.0
2025-05-21 09:43:07 +03:00
dependabot[bot]
4cf1468907
Bump golang.org/x/mod from 0.17.0 to 0.24.0
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.17.0 to 0.24.0.
- [Commits](https://github.com/golang/mod/compare/v0.17.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-version: 0.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-21 06:30:29 +00:00
Gabriel Adrian Samfira
c5c35f1324 Use default values for ref and push to project
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-21 05:03:07 +00:00
Gabriel
0068119c34
Merge pull request #395 from gabriel-samfira/add-cli-to-docker-image
Add CLI to docker image
2025-05-21 00:15:54 +03:00
Gabriel Adrian Samfira
269c6064e7 Add CLI to docker image
This change adds the GARM cli to the docker image.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 21:15:08 +00:00
Gabriel
b7798404f8
Merge pull request #394 from cloudbase/update-build-and-push
Allow for nightly builds
2025-05-20 23:20:55 +03:00
Gabriel Adrian Samfira
bdcc817def Enable daily cron
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 20:10:08 +00:00
Gabriel Adrian Samfira
b41318c948 Allow for nightly builds
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 17:00:59 +00:00
Gabriel
dee6bf7c9a
Merge pull request #393 from gabriel-samfira/add-gitea
Add gitea
2025-05-20 19:26:46 +03:00
Gabriel Adrian Samfira
1fc72ab5c8 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 16:12:45 +00:00
Gabriel Adrian Samfira
1fe09548bc Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 13:52:16 +00:00
Gabriel Adrian Samfira
b4268e6bab Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:52:13 +00:00
Gabriel Adrian Samfira
6994c8ce05 Add copyright header
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:43:29 +00:00
Gabriel Adrian Samfira
f0753eeb22 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-20 09:22:55 +00:00
Gabriel Adrian Samfira
b2d5609352 Add some tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-19 19:45:45 +00:00
Gabriel Adrian Samfira
bb798a288a Properly set webhook secret
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-16 23:58:39 +00:00
Gabriel Adrian Samfira
6a168ba813 Enable orgs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-16 23:02:01 +00:00
Gabriel Adrian Samfira
5dfcfc542e Implement webhooks install for gitea
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-16 20:24:11 +00:00
Gabriel Adrian Samfira
08511e2e7f Account for gitea credentials in cache and watchers
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-15 09:15:44 +00:00
Gabriel Adrian Samfira
b4e92a69c9 Fix existing tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 23:20:18 +00:00
Gabriel Adrian Samfira
0270117e8d Fix lint errors
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 22:01:11 +00:00
Gabriel Adrian Samfira
39ac658527 Add forge type to repo list
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 21:33:46 +00:00
Gabriel Adrian Samfira
3fe4cef884 Cleanup unused code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 21:14:31 +00:00
Gabriel Adrian Samfira
f66b651b59 Fix findEndpointForJob
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 21:09:02 +00:00
Gabriel Adrian Samfira
56be5eb698 Do not load scalesets and runners in parallel
Both functions read and write to the same map. We should switch
to sync.Map

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 15:36:53 +00:00
Gabriel Adrian Samfira
8538a4ae8a Make sure websocket hub exits properly
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 15:22:27 +00:00
Gabriel Adrian Samfira
823a9e4b82 Add Gitea endpoints and credentials
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-14 00:34:54 +00:00
Gabriel Adrian Samfira
40e6581a75 Rename GitHub specific types
This change renames a lot of variables, types and functions to be more
generic. The goal is to allow GARM to add more forges in the future.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-12 21:47:13 +00:00
Gabriel Adrian Samfira
4890eb4732 Add EndpointType
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-12 17:32:37 +00:00
Gabriel Adrian Samfira
ef676488b7 Use cache for github client
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-10 20:08:51 +00:00
Gabriel
5dbaa351d2
Merge pull request #392 from gabriel-samfira/docs
Slight rewording
2025-05-10 09:15:11 +03:00
Gabriel Adrian Samfira
41700cd958 Slight rewording
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-10 06:14:38 +00:00
Gabriel
fd6f01d2c0
Merge pull request #391 from gabriel-samfira/add-some-docs
Add some info about scale sets
2025-05-10 00:29:19 +03:00
Gabriel Adrian Samfira
979c07adbe Add some info about scale sets
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-09 21:28:29 +00:00
Gabriel
6b4c4f610e
Merge pull request #390 from gabriel-samfira/add-some-parallel-startup
Load entities in parallel
2025-05-09 01:31:10 +03:00
Gabriel Adrian Samfira
68183384dc Load entities in parallel
This change uses an error group to load different DB resources
in parallel.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-08 22:26:40 +00:00
Gabriel
49147a015a
Merge pull request #389 from gabriel-samfira/fixes-and-rate-limits
Add rate limit cache and fixes
2025-05-09 00:49:28 +03:00
Gabriel Adrian Samfira
1a719567ff Add rate limit cache and fixes
This change adds a loop that keeps a cache of credentials rate limits
as reported by the github API. The cache is updated every 30 seconds
and is purely informational for the user.

This change also adds some caching improvements. Functions that return
values from the cache as lists, will now sort by ID or creation date.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-08 21:39:55 +00:00
Gabriel
16af8fd97f
Merge pull request #387 from gabriel-samfira/add-tools-update
Add tools update routine and cleanup logging
2025-05-08 11:35:41 +03:00
Gabriel Adrian Samfira
2e9535530d Fix entity update handler
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-08 08:27:41 +00:00
Gabriel Adrian Samfira
a38d72a01c Add runner group to the scale set list output
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-08 08:12:29 +00:00
Gabriel Adrian Samfira
52007f4ffa Add tools update routine and cleanup logging
This change adds an update routine in the cache worker, for github tools
downloads.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-07 23:07:58 +00:00
Gabriel
ffbb3b8d41
Merge pull request #386 from gabriel-samfira/add-cache-worker
Add cache worker
2025-05-07 11:31:18 +03:00
Gabriel Adrian Samfira
90200ffa71 Do not clobber pools and scaleset caches on update
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-07 08:15:29 +00:00
Gabriel Adrian Samfira
d0c9462a5d Add cache worker
Add dedicated worker to maintain cache.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-07 08:01:36 +00:00
Gabriel
e49b35d3d0
Merge pull request #376 from gabriel-samfira/scalesets
Add scale sets
2025-05-07 00:12:57 +03:00
Gabriel Adrian Samfira
2f2ff62411 Deduplicate code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-06 20:59:41 +00:00
Gabriel Adrian Samfira
f7cd743a9c Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-06 19:37:07 +00:00
Gabriel Adrian Samfira
a80b900ee9 Update dependencies
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-06 18:27:20 +00:00
Gabriel Adrian Samfira
0e1fa0018b Add some more caching, record scaleset jobs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-06 17:50:12 +00:00
Gabriel Adrian Samfira
2f3c74562e Add instance cache
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-05 23:34:53 +00:00
Gabriel Adrian Samfira
9f640965e2 revert main
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-05 21:12:20 +00:00
Gabriel Adrian Samfira
1d093cc336 Slight refactor; add creds cache worker
* Split the main function into a couple of more functions
* Add credentials, entity, pool and scaleset cache
* add credentials worker that updates the cache

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-05 18:21:57 +00:00
Gabriel Adrian Samfira
3b3095c546 Scale sets are unique within a runner group
You can have multiple scale sets with the same name, as long as
they live in different runner groups.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:57:50 +00:00
Gabriel Adrian Samfira
77895d9c89 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:41 +00:00
Gabriel Adrian Samfira
ff383ea493 Add db scaleset tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:41 +00:00
Gabriel Adrian Samfira
2a5e374ae6 Remove unused field
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:41 +00:00
Gabriel Adrian Samfira
c601f88cf7 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:41 +00:00
Gabriel Adrian Samfira
92d04c8e8d Add tests for cache and locking
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
059734f064 Add runner periodic cleanup check
Adds a periodic cleanup function that cross checks runners between github,
the provider and the GARM database. If an inconsistency is found, GARM will
attempt to fix it.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
73340da322 Add RateLimit() function to gh client
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
fafe98e62f Update go-github
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
22302fdd7a Add scaleset watcher to provider
Fixes provider not spawning runners for newly added scale set

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
64d1501b0e DeleteInstance should noop if error not found
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
4b1d51f1d0 Fix nil pointer deref
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
55b4e74066 Update mocks
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
884be62a4d Fix lint errors
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
a4ac85aa4a Update CLI to show scale sets
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
f2ad7a3481 Fix leftover instances and refactor
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
004ad1f124 Add provider worker code
Runners now get created and cleaned up in scale sets.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
436fd7746f WiP
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
020210d6ad Handle scale up and down; add provider worker
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
7376a5fe74 Fix scale set restart logic
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
bc470c5f78 WiP
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
8c62b6de8c Obey enabled/disabled status
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
d949cecbe7 Keep a cache of runners in the scaleset worker
We will need to run various checks against the runners that are managed
by a scale set. The runners are updated by the DB watcher, so we should
always have an up to date view of their state. We can then confidently
monitor them without needing to query the DB.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
94f264d444 Handle JobStarted and JobCompleted
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
8d10dd4716 Update garm-provider-common
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
fc4bd863aa Add some db functions to handle scaleset instances
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
c177c31147 Add some message handling
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
12f40a5352 Fix refresh session
It seems that Status is a string when you create a session, but a number
when you refresh it (?).

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
19ba210804 Several fixes
* Close response body in scaleset client
* Wait for message listener loop to exit before attempting restart
* Add LastMessageID field to scaleset model and function to update it

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
a2aeac731c Scale set workers properly come online
This adds the workers needed to start listening for scale set messages.
There is no handling of messages yet.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
6a5c309399 Add some worker code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
7174e030e2 Add scaleset commands
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
7e1a83c79a Add API endpoint for some scaleset ops
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
85eac363d5 Add ScaleSet models, functions and types
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
5ba53adf84 Switch to locking package
The locking logic was added to its own package as it may need to be used
by other parts of the code.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
e51f19acc8 Fix lint errors
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
d7d6d1e31a Add mocks
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
51c7d2a806 Add scaleset types
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel Adrian Samfira
79b9a1583c Add scaleset client
This change moves the github client to a subpackage in utils
and adds the scaleset github client code.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-03 22:29:40 +00:00
Gabriel
cc1470fe08
Merge pull request #382 from gabriel-samfira/set-base-url
set base URL in ghinstallation transport
2025-05-04 01:28:16 +03:00
Gabriel Adrian Samfira
2f1f61bfc6
set base URL in ghinstallation transport
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-05-04 00:51:25 +03:00
Gabriel
0d53dce16f
Merge pull request #378 from gabriel-samfira/update-deps
Update all dependencies
2025-04-17 18:12:49 +03:00
Gabriel Adrian Samfira
d27bd40531
Update all dependencies
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-04-17 18:07:33 +03:00
Gabriel
4bedb86cf0
Merge pull request #372 from cloudbase/dependabot/go_modules/github.com/prometheus/client_golang-1.22.0
Bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0
2025-04-14 10:51:46 +03:00
dependabot[bot]
b2f84264d4
Bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.21.1 to 1.22.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.21.1...v1.22.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-09 06:27:01 +00:00
Gabriel
69f6b4f541
Merge pull request #370 from cloudbase/dependabot/go_modules/golang.org/x/oauth2-0.29.0
Bump golang.org/x/oauth2 from 0.28.0 to 0.29.0
2025-04-07 10:56:50 +03:00
dependabot[bot]
595cf51be0
Bump golang.org/x/oauth2 from 0.28.0 to 0.29.0
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.28.0 to 0.29.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-version: 0.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 07:52:29 +00:00
Gabriel
52cf0f5163
Merge pull request #371 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.37.0
Bump golang.org/x/crypto from 0.36.0 to 0.37.0
2025-04-07 10:51:16 +03:00
dependabot[bot]
4c5c3a0e93
Bump golang.org/x/crypto from 0.36.0 to 0.37.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.36.0 to 0.37.0.
- [Commits](https://github.com/golang/crypto/compare/v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 07:46:55 +00:00
Gabriel
16d9b6d650
Merge pull request #369 from cloudbase/dependabot/go_modules/golang.org/x/sync-0.13.0
Bump golang.org/x/sync from 0.12.0 to 0.13.0
2025-04-07 10:45:44 +03:00
dependabot[bot]
6064c07611
Bump golang.org/x/sync from 0.12.0 to 0.13.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.12.0 to 0.13.0.
- [Commits](https://github.com/golang/sync/compare/v0.12.0...v0.13.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 07:11:47 +00:00
Gabriel
aeaf594f3b
Merge pull request #368 from cloudbase/dependabot/go_modules/go_modules-ba6d682d0f
Bump github.com/golang-jwt/jwt/v4 from 4.5.1 to 4.5.2 in the go_modules group
2025-03-22 20:23:18 +02:00
dependabot[bot]
cad9965497
Bump github.com/golang-jwt/jwt/v4 in the go_modules group
Bumps the go_modules group with 1 update: [github.com/golang-jwt/jwt/v4](https://github.com/golang-jwt/jwt).


Updates `github.com/golang-jwt/jwt/v4` from 4.5.1 to 4.5.2
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v4.5.1...v4.5.2)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v4
  dependency-type: indirect
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-22 05:16:51 +00:00
Gabriel
17f3f3e0fa
Merge pull request #367 from cloudbase/dependabot/go_modules/go_modules-036d30de33
Bump github.com/golang-jwt/jwt/v5 from 5.2.1 to 5.2.2 in the go_modules group
2025-03-22 07:15:56 +02:00
dependabot[bot]
1c0d56237c
Bump github.com/golang-jwt/jwt/v5 in the go_modules group
Bumps the go_modules group with 1 update: [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt).


Updates `github.com/golang-jwt/jwt/v5` from 5.2.1 to 5.2.2
- [Release notes](https://github.com/golang-jwt/jwt/releases)
- [Changelog](https://github.com/golang-jwt/jwt/blob/main/VERSION_HISTORY.md)
- [Commits](https://github.com/golang-jwt/jwt/compare/v5.2.1...v5.2.2)

---
updated-dependencies:
- dependency-name: github.com/golang-jwt/jwt/v5
  dependency-type: direct:production
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-21 22:11:26 +00:00
Gabriel
b168fad0aa
Merge pull request #366 from cloudbase/dependabot/go_modules/github.com/BurntSushi/toml-1.5.0
Bump github.com/BurntSushi/toml from 1.4.0 to 1.5.0
2025-03-21 13:39:21 +02:00
Gabriel
beeb82a9cb
Merge pull request #365 from cloudbase/dependabot/go_modules/github.com/go-openapi/errors-0.22.1
Bump github.com/go-openapi/errors from 0.22.0 to 0.22.1
2025-03-21 13:39:01 +02:00
Gabriel
587d432fb5
Merge pull request #364 from cloudbase/dependabot/go_modules/github.com/go-openapi/swag-0.23.1
Bump github.com/go-openapi/swag from 0.23.0 to 0.23.1
2025-03-21 13:38:40 +02:00
dependabot[bot]
76489fb3cf
Bump github.com/BurntSushi/toml from 1.4.0 to 1.5.0
Bumps [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/BurntSushi/toml/releases)
- [Commits](https://github.com/BurntSushi/toml/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: github.com/BurntSushi/toml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 06:54:48 +00:00
dependabot[bot]
632531f735
Bump github.com/go-openapi/errors from 0.22.0 to 0.22.1
Bumps [github.com/go-openapi/errors](https://github.com/go-openapi/errors) from 0.22.0 to 0.22.1.
- [Commits](https://github.com/go-openapi/errors/compare/v0.22.0...v0.22.1)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/errors
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 06:54:43 +00:00
dependabot[bot]
2aeb24858f
Bump github.com/go-openapi/swag from 0.23.0 to 0.23.1
Bumps [github.com/go-openapi/swag](https://github.com/go-openapi/swag) from 0.23.0 to 0.23.1.
- [Commits](https://github.com/go-openapi/swag/compare/v0.23.0...v0.23.1)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/swag
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-13 06:27:27 +00:00
Gabriel
a734f82e45
Merge pull request #363 from gabriel-samfira/update-deps
Update dependencies
2025-03-06 14:15:50 +02:00
Gabriel Adrian Samfira
e3b46209a5 Update dependencies
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-03-06 12:00:19 +00:00
Gabriel
99f56606eb
Merge pull request #356 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.35.0
Bump golang.org/x/crypto from 0.34.0 to 0.35.0
2025-02-25 10:47:32 +02:00
dependabot[bot]
ccc18d5006
Bump golang.org/x/crypto from 0.34.0 to 0.35.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.34.0 to 0.35.0.
- [Commits](https://github.com/golang/crypto/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-25 06:51:21 +00:00
Gabriel
77a503b61d
Merge pull request #355 from gabriel-samfira/update-deps
Update dependencies
2025-02-24 10:04:09 +02:00
Gabriel Adrian Samfira
5415121a70 Update dependencies
This change updates all dependencies.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-02-24 07:59:10 +00:00
Gabriel
f2b43bac77
Merge pull request #329 from gabriel-samfira/add-backoff
Add a backoff mechanism when deleting runners
2025-02-13 13:12:09 +02:00
Gabriel
bf4636417b
Merge pull request #328 from gabriel-samfira/add-busy-timeout
Add knob to tweak _busy_timeout
2025-02-13 13:10:15 +02:00
Gabriel
09e3df25ba
Merge pull request #349 from cloudbase/dependabot/go_modules/github.com/jedib0t/go-pretty/v6-6.6.6
Bump github.com/jedib0t/go-pretty/v6 from 6.6.5 to 6.6.6
2025-02-11 10:49:19 +02:00
dependabot[bot]
17c9b0a841
Bump github.com/jedib0t/go-pretty/v6 from 6.6.5 to 6.6.6
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.6.5 to 6.6.6.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.6.5...v6.6.6)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-11 06:41:57 +00:00
Gabriel
aa60ae9c09
Merge pull request #348 from gabriel-samfira/change-event-log
Update event logging
2025-02-10 15:21:35 +02:00
Gabriel Adrian Samfira
b8e77cb125 Update event logging
Ping events are no longer logged. Unknown events are now logged as Debug.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-02-10 13:15:35 +00:00
Gabriel
ce7c67a8a7
Merge pull request #347 from gabriel-samfira/add-created-at
Add additional info when listing resources
2025-02-10 14:51:20 +02:00
Gabriel Adrian Samfira
c0245a18f7 Add additional info when listing resources
This change adds a --long option to most commands and includes the
CreateAt and UpdatedAt fields in the output.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-02-10 12:45:30 +00:00
Gabriel
719bcd05aa
Merge pull request #346 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.33.0
Bump golang.org/x/crypto from 0.32.0 to 0.33.0
2025-02-10 10:28:38 +02:00
dependabot[bot]
4a05fe600c
Bump golang.org/x/crypto from 0.32.0 to 0.33.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.32.0 to 0.33.0.
- [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-10 06:46:58 +00:00
Gabriel
ea4f605bf1
Merge pull request #342 from gabriel-samfira/relax-validation
Relax description validation
2025-02-05 22:23:27 +02:00
Gabriel
d4ce174bab
Merge pull request #343 from gabriel-samfira/relax-webhook-url
Relax URLs validation
2025-02-05 22:19:16 +02:00
Gabriel Adrian Samfira
beafcb6316 Relax description validation
Description should not be mandatory when defining a github endpoint.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-02-05 20:18:56 +00:00
Gabriel Adrian Samfira
86d6517a5d Relax URLs validation
Webhook URL was not mandatory in previous versions. While it is needed
if users plan to use the install webhook feature, it is not required if
you want to install it yourself.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-02-05 20:10:02 +00:00
Gabriel
001465d0a2
Merge pull request #326 from cloudbase/dependabot/go_modules/golang.org/x/crypto-0.32.0
Bump golang.org/x/crypto from 0.31.0 to 0.32.0
2025-02-05 10:16:30 +02:00
dependabot[bot]
83001abbae
Bump golang.org/x/crypto from 0.31.0 to 0.32.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.31.0 to 0.32.0.
- [Commits](https://github.com/golang/crypto/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-05 08:11:41 +00:00
Gabriel
453ce1004c
Merge pull request #340 from cloudbase/dependabot/go_modules/golang.org/x/sync-0.11.0
Bump golang.org/x/sync from 0.10.0 to 0.11.0
2025-02-05 10:10:27 +02:00
dependabot[bot]
c179436f97
Bump golang.org/x/sync from 0.10.0 to 0.11.0
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-05 08:00:13 +00:00
Gabriel
45957e45ba
Merge pull request #341 from cloudbase/dependabot/go_modules/golang.org/x/oauth2-0.26.0
Bump golang.org/x/oauth2 from 0.25.0 to 0.26.0
2025-02-05 09:59:01 +02:00
dependabot[bot]
0932e94799
Bump golang.org/x/oauth2 from 0.25.0 to 0.26.0
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.25.0 to 0.26.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-05 07:15:38 +00:00
Gabriel
5ec6c25246
Merge pull request #335 from cloudbase/gabriel-samfira-patch-1
Update integration-tests.yml
2025-01-31 21:04:32 +02:00
Gabriel
e255c90213
Update integration-tests.yml 2025-01-31 20:59:25 +02:00
Gabriel Adrian Samfira
edbaf47970 Add a backoff mechanism when deleting runners
This change adds a backoff mechanism when deleting github runners.
If the delete operation fails, we record the event and retry with
a geometric progression of 1.5 starting from 5 seconds, which is the
pool consolidation timeout.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-01-28 23:00:10 +00:00
Gabriel Adrian Samfira
6814b69a09 Add knob to tweak _busy_timeout
In SQLite3 we may need to set a busy_timeout in the case of instances
with high load. This change adds a knob that allows users to set a
timeout if a database is locked for writing by another routine.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2025-01-28 20:07:07 +00:00
Gabriel
e0e60d42c8
Merge pull request #327 from fabi200123/update-docs
Update Performance Considerations - Cached runners section
2025-01-17 13:11:21 +02:00
Fabian Fulga
e221698299 Update Performance Considerations - Cached runners section 2025-01-17 10:14:24 +02:00
Gabriel
b60fad59d5
Merge pull request #324 from cloudbase/dependabot/go_modules/github.com/bradleyfalzon/ghinstallation/v2-2.13.0
Bump github.com/bradleyfalzon/ghinstallation/v2 from 2.12.0 to 2.13.0
2025-01-07 00:19:14 +02:00
Gabriel
a040dde9b4
Merge pull request #325 from cloudbase/dependabot/go_modules/golang.org/x/oauth2-0.25.0
Bump golang.org/x/oauth2 from 0.24.0 to 0.25.0
2025-01-07 00:18:20 +02:00
dependabot[bot]
83ee1724db
Bump golang.org/x/oauth2 from 0.24.0 to 0.25.0
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 06:38:40 +00:00
dependabot[bot]
5d6ace6a2c
Bump github.com/bradleyfalzon/ghinstallation/v2 from 2.12.0 to 2.13.0
Bumps [github.com/bradleyfalzon/ghinstallation/v2](https://github.com/bradleyfalzon/ghinstallation) from 2.12.0 to 2.13.0.
- [Release notes](https://github.com/bradleyfalzon/ghinstallation/releases)
- [Commits](https://github.com/bradleyfalzon/ghinstallation/compare/v2.12.0...v2.13.0)

---
updated-dependencies:
- dependency-name: github.com/bradleyfalzon/ghinstallation/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-03 06:41:00 +00:00
Gabriel
f43f797883
Merge pull request #322 from gabriel-samfira/update-deps
Update dependencies
2024-12-20 20:59:10 +02:00
Gabriel Adrian Samfira
c42c3f580e Update dependencies
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-12-20 18:54:05 +00:00
Gabriel
72034d445a
Merge pull request #321 from cloudbase/dependabot/go_modules/github.com/jedib0t/go-pretty/v6-6.6.5
Bump github.com/jedib0t/go-pretty/v6 from 6.6.4 to 6.6.5
2024-12-20 20:47:47 +02:00
dependabot[bot]
e96145833c
Bump github.com/jedib0t/go-pretty/v6 from 6.6.4 to 6.6.5
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.6.4 to 6.6.5.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.6.4...v6.6.5)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-20 18:42:29 +00:00
Gabriel
e69838b678
Merge pull request #320 from cloudbase/gabriel-samfira-patch-2
Create dependabot.yml
2024-12-20 20:41:22 +02:00
Gabriel
1f3c7cd34a
Create dependabot.yml 2024-12-20 20:35:04 +02:00
Gabriel
54505289d5
Merge pull request #319 from gabriel-samfira/update-deps
Update dependencies
2024-12-12 23:48:52 +02:00
Gabriel Adrian Samfira
f0aaf20998
Update dependencies
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-12-12 23:42:01 +02:00
Gabriel
1cb2d70546
Merge pull request #318 from gabriel-samfira/fix-nil-pointer-cli
Fix nil pointer dereference when rendering message
2024-12-12 10:49:09 +02:00
Gabriel Adrian Samfira
f8b4118306
Fix nil pointer dereference when rendering message
We failed to properly check the error of the update url call before
trying to access the payload, which lead to a panic in the CLI. This
change should fix that.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-12-12 09:49:42 +02:00
Gabriel
c4a7a59bc9
Merge pull request #316 from gabriel-samfira/fix-run-as-user
Fix hardcoded user value in template
2024-12-05 01:28:43 +02:00
Gabriel Adrian Samfira
67928ccd94
Fix hardcoded user value in template
The User option in the systemd unit file used when JIT configs are enabled
had a hardcoded value of "runner". This change fixes that oversight.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-12-05 00:04:11 +02:00
Gabriel
7d889f0cdd
Merge pull request #315 from mercedes-benz/fix/makefile
fix: remove duplication in Makefile
2024-11-26 16:59:14 +02:00
Michael Kuhnt
53bc1eedce fix: remove duplication in Makefile 2024-11-26 15:04:53 +01:00
Gabriel
8e13588edd
Merge pull request #314 from mercedes-benz/improve_error_message
Improve error messages in garm log
2024-11-26 10:44:41 +02:00
Michael Kuhnt
6167d8c7fd lint: exclude gosec G115 2024-11-26 09:23:58 +01:00
Michael Kuhnt
3a95b8f704 fix linter finding 2024-11-26 07:53:02 +01:00
Michael Kuhnt
386aba18c0 set specific linter version 2024-11-26 07:49:08 +01:00
Michael Kuhnt
d6de59619d commit suggestion 2024-11-22 16:49:56 +01:00
Michael Kuhnt
935c9dcd96
Update database/sql/jobs.go
Co-authored-by: Gabriel <samfiragabriel@gmail.com>
2024-11-22 16:40:23 +01:00
Michael Kuhnt
8a31d81faf ignore workflow_jobs without labels 2024-11-22 11:48:59 +01:00
Michael Kuhnt
c5c74a8dfc add runner name in error message 2024-11-22 11:48:59 +01:00
Gabriel
06dfc2708d
Merge pull request #306 from gabriel-samfira/fix-conflicting-options
Remove conflicting short hand option
2024-10-23 16:43:54 +03:00
Gabriel Adrian Samfira
2273b1de19 Remove conflicting short hand option
The --format command line option is persistent to allow all commands to
output to either json or table. The shorthand of this option caused a
conflict with other subcommands that also define the -f option. Removing
the persitent short form option.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-10-23 13:38:05 +00:00
Gabriel
54aa3815df
Merge pull request #302 from fabi200123/cached-runner-docs
Add Using Cached Runner documentation
2024-10-22 13:22:56 +03:00
Fabian Fulga
8515bf1083 Add Using Cached Runner documentation 2024-10-16 08:28:12 +03:00
Gabriel
465b12beb5
Merge pull request #299 from gabriel-samfira/use-errors-wrap
Use errors.Wrap() in repositories.go
2024-10-06 14:30:36 +03:00
Gabriel
6e38e23cdc
Merge pull request #301 from gabriel-samfira/copy-ca-certs
Copy the CA certificates to final image
2024-09-28 22:40:32 +03:00
Gabriel Adrian Samfira
1ba14f858d Copy the CA certificates to final image
The busybox image does not contain CA certificares. This adds them from
the builder stage.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-28 19:30:20 +00:00
Gabriel
72e8aa10ee
Merge pull request #300 from gabriel-samfira/add-default-value
Add a default value to the new --format option
2024-09-28 22:26:54 +03:00
Gabriel Adrian Samfira
f9abb30128 Add a default value to the new --format option
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-28 19:21:20 +00:00
Gabriel
5323fcb513
Merge pull request #298 from gabriel-samfira/add-format-option
Add --format command line option
2024-09-28 22:15:13 +03:00
Gabriel Adrian Samfira
36b9e9f296 Use errors.Wrap() in repositories.go
The API code unwraps errors wrapped by the errors.Wrap() function. It
falls back to 500 error if it can't determine any other error type.

Ultimately we need to migrate to the fmt.Errorf() pattern. But for now
at least, we need to return proper errors. Any 500 error will not output
details to the API. Neither will 401 for similar reasons.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-28 19:13:05 +00:00
Gabriel Adrian Samfira
63000113ee Add --format command line option
This change adds a --format command line option to the GARM cli. This
option accepts either json or table as a value.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-28 19:09:45 +00:00
Gabriel
cf231c9d8d
Merge pull request #297 from gabriel-samfira/add-omitempty
Add omitempty to all struct fields
2024-09-28 21:25:07 +03:00
Gabriel Adrian Samfira
2dfde30aad Add omitempty to all struct fields
The JSON that gets returned by the API is filled with empty values
which serve no purpose. Adding omitempty will skip empty values.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-28 18:19:14 +00:00
Gabriel
bdb26c1827
Merge pull request #296 from gabriel-samfira/make-tag-search-case-insensitive
Do a case insensitive search for tags
2024-09-28 21:03:29 +03:00
Gabriel Adrian Samfira
e5fd702544 Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-27 08:05:43 +00:00
Gabriel Adrian Samfira
c319341ec5 Do a case insensitive search for tags
This change switches to a case insensitive search for pool tags.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-09-27 07:54:29 +00:00
Gabriel
3a2061afb9
Merge pull request #278 from fabi200123/version-v3
Add provider interface versioning
2024-09-04 15:15:46 +03:00
Fabian Fulga
dcff6f9854 Add getProviderBaseParams function in basePoolManager 2024-09-02 15:25:44 +03:00
Fabian Fulga
7074f01541 Move ValidateResult to common package 2024-09-02 10:39:45 +03:00
Fabian Fulga
08244161a1 Update garm-provider-common package 2024-08-22 11:40:37 +03:00
Fabian Fulga
03f280da59 Version provider interface 2024-08-21 16:14:38 +03:00
Gabriel
deb30e1d25
Merge pull request #288 from gabriel-samfira/use-lxd-image-mirror
Allow using LXD image mirror
2024-08-14 23:57:41 +03:00
Gabriel Adrian Samfira
9a6f0e7926 Pin go version
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-14 20:52:10 +00:00
Gabriel Adrian Samfira
f5992b7344 Allow using LXD image mirror
This change allows GARM tests to use a mirror for LXD images, allowing
for faster image downloads.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-14 19:44:23 +00:00
Gabriel
3b1e3c77e1
Merge pull request #287 from gabriel-samfira/switch-to-self-hosted
Switch to self hosted runner
2024-08-14 20:14:52 +03:00
Gabriel Adrian Samfira
d5cbc5bfb2 Switch to self hosted runner
GitHub hosted runners seem to have issues with LXD containers.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-12 21:15:47 +00:00
Gabriel
fc32978c63
Merge pull request #286 from gabriel-samfira/replace-ngrok
Replace ngrok
2024-08-12 22:29:37 +03:00
Gabriel Adrian Samfira
e1e46211a1 Replace ngrok
This change switches the integration tests to an alternate tunneling
service.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-12 19:22:52 +00:00
Gabriel
237afdb25d
Merge pull request #284 from gabriel-samfira/prepare-v0.1.5
Prepare v0.1.5
2024-08-08 15:32:37 +03:00
Gabriel Adrian Samfira
926797dda5 Pin provider versions and switch to busybox
Thic change pins all providers to a released version. We also switched
the GARM image to busybox. This adds an extra ~45MB, but we get an image
we can exec into.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-08 12:22:16 +00:00
Gabriel
82d70d2310
Merge pull request #4 from fabi200123/small-nits
Update docs
2024-08-08 15:05:17 +03:00
Fabian Fulga
b9aafbe65e Update docs 2024-08-08 15:01:24 +03:00
Gabriel Adrian Samfira
a12ad2fa89 Fix example spaces vs tabs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-08 09:29:15 +00:00
Gabriel Adrian Samfira
932ee4693e Remove extra doc
The database.md doc has been added to config.md.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-08 09:16:09 +00:00
Gabriel Adrian Samfira
1a54bcfc35 Restructure docs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-08 09:13:55 +00:00
Gabriel Adrian Samfira
6640599584 Add more info on events
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-06 15:18:18 +00:00
Gabriel Adrian Samfira
9b0633c557 Update quickstart and using_garm, add events.md
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-06 15:18:18 +00:00
Gabriel Adrian Samfira
35f4bea269 Update docs
Reword some phrases, update links and steps.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-06 15:18:18 +00:00
Gabriel
56b0e6065a
Merge pull request #283 from gabriel-samfira/add-json-tags
Add JSON tags to the ChangePayload struct
2024-08-06 16:53:12 +03:00
Gabriel Adrian Samfira
a7f1a51a7d Add JSON tags to the ChangePayload struct
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-06 13:43:58 +00:00
Gabriel
516908f26c
Merge pull request #282 from gabriel-samfira/update-common
Update garm-provider-common
2024-08-03 19:16:53 +03:00
Gabriel Adrian Samfira
bc4285dc80 Update garm-provider-common
Use the websocket reader from within garm-provider-common.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-03 16:07:21 +00:00
Gabriel
a5b15789a1
Merge pull request #281 from gabriel-samfira/cleanup-websocket-urls
Rename websocket URLs
2024-08-03 01:29:05 +03:00
Gabriel Adrian Samfira
79c1e47427 Rename websocket URLs
Given that we now have multiple websocket URLs (logs and events), this
change categorizes them under the same prefix.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-02 22:19:51 +00:00
Gabriel
7fe2a3ad34
Merge pull request #280 from gabriel-samfira/generalize-ws-reader
Generalize the websocket reader
2024-08-03 00:27:43 +03:00
Gabriel Adrian Samfira
5c45f54ef4 Generalize the websocket reader
This change adds a new message handler that users of the reader can use
to handle websocket messages. Packages should never print to console by
themselves.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-08-02 21:18:31 +00:00
Gabriel
6835419daf
Merge pull request #279 from gabriel-samfira/scope-entities-to-endpoint
Fix: Scope entities to endpoint
2024-08-01 13:19:42 +03:00
Gabriel Adrian Samfira
cc6e985629 Fix: Scope entities to endpoint
This change scopes all github entities to a github endpoint, allowing
users to have the same repo/org/enterprise created for each endpoint.

This way, if your username is the same on github.com and on your GHES
server, and you have the same repository name or org in both places,
GARM can now handle that situation.

This change also fixes a leaky watcher in the pool manager.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-29 17:35:57 +00:00
Gabriel
f64ffa8d92
Merge pull request #277 from gabriel-samfira/slight-docs-reword
Reword the section about labels
2024-07-07 00:05:27 +03:00
Gabriel Adrian Samfira
411dcea4fb Reword the section about labels
This change removes a stray line in the quickstart and rewords
the section about labels a bit.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-06 21:02:54 +00:00
Gabriel
59de9cdf93
Merge pull request #275 from gabriel-samfira/add-event-stream
Add event stream
2024-07-05 23:06:09 +03:00
Gabriel Adrian Samfira
2554f70b89 Replace time.After with time.NewTimer
Improper use of time.After can lead to memory leaks if the timer never
gets a chance to fire.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
49f1b7aa14 Set read limit to 16 KB
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
a2c606b87d Simplify logic
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
5b24b9e56b Fix shadowing bug in job create function
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
5c5b2256bb Create common utility function for ws
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
246f826b76 Validate filter payload
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
9f8659abd6 Add events websocket endpoint
This change adds a new websocket endpoint for database events. The events
endpoint allows clients to stream events as they happen in GARM. Events
are defined as a structure containning the event type (create, update, delete),
the database entity involved (instances, pools, repos, etc) and the payload
consisting of the object involved in the event. The payload translates
to the types normally returned by the API and can be deserialized as one
of the types present in the params package.

The events endpoint is a websocket endpoint and it accepts filters as
a simple json send over the websocket connection. The filters allows the
user to specify which entities are of interest, and which operations should
be returned. For example, you may be interested in changes made to pools
or runners, in which case you could create a filter that only returns
update operations for pools. Or update and delete operations.

The filters can be defined as:

{
  "filters": [
    {
      "entity_type": "instance",
      "operations": ["update", "delete"]
    },
    {
      "entity_type": "pool"
    },
  ],
  "send_everything": false
}

This would return only update and delete events for instances and all events
for pools. Alternatively you can ask GARM to send you everything:

{
  "send_everything": true
}

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel Adrian Samfira
dd1740c189 Refactor the websocket client and add fixes
The websocket client and hub interaction has been simplified a bit.
The hub now acts only as a tee writer to the various clients that
register. Clients must register and unregister explicitly. The hub
is no longer passed in to the client.

Websocket clients now watch for password changes or jwt token expiration
times. Clients are disconnected if auth token expires or if the password
is changed.

Various aditional safety checks have been added.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:55:35 +00:00
Gabriel
ca7f20b62d
Merge pull request #276 from gabriel-samfira/add-version-to-api-response
Add version to controller info response
2024-07-05 15:54:45 +03:00
Gabriel Adrian Samfira
42ae3c52d1 Add version to controller info response
This change adds the GARM server version to the controller info response.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-05 12:49:16 +00:00
Gabriel
dcee09281b
Merge pull request #274 from gabriel-samfira/make-durations-configuratble
Allow configuration of job backoff interval
2024-07-02 12:03:05 +03:00
Gabriel Adrian Samfira
892a62bfe4 Allow configuration of job backoff interval
GARM has a backoff interval when consuming queued jobs. This backoff
is intended to allow any potential idle runners to pick up a job before
GARM attempts to spin up a new one. This change allows users to set a
custom backoff interval or disable it altogether by setting it to 0.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-07-01 10:27:31 +00:00
Gabriel
8f0d44742e
Merge pull request #269 from gabriel-samfira/remove-update-state
Use watcher and get rid of RefreshState()
2024-06-21 16:51:54 +03:00
Gabriel Adrian Samfira
daaca0bd8f Use watcher and get rid of RefreshState()
This change uses the database watcher to watch for changes to the
github entities, credentials and controller info.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-21 13:47:48 +00:00
Gabriel
38127af747
Merge pull request #268 from gabriel-samfira/lower-log-level
Lower the log level of ignored jobs
2024-06-20 18:35:24 +03:00
Gabriel Adrian Samfira
1dfa74efd8 Lower the log level of ignored jobs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-20 15:30:25 +00:00
Gabriel
98b8a7f15f
Merge pull request #267 from fabi200123/fix-set-watcher
Remove duplicate of watcher.SetWatcher()
2024-06-20 17:59:25 +03:00
Fabian Fulga
61c9470bcf Remove duplicate of watcher.SetWatcher 2024-06-20 17:37:11 +03:00
Gabriel
5eef3b68cb
Merge pull request #266 from gabriel-samfira/consume-watcher-events
Consume events before testing
2024-06-20 15:50:30 +03:00
Gabriel Adrian Samfira
8bf979fe1c Consume events before testing
The watcher uses a buffered channel, so we may get stray events that
we need to consume before generating new ones in the tests.

This is just for testing purposes. In actual use cases, we never expect
to only have one event generated.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-20 12:38:36 +00:00
Gabriel
c188a6f2c1
Merge pull request #263 from gabriel-samfira/add-database-watcher
Add database watcher
2024-06-20 15:01:53 +03:00
Gabriel Adrian Samfira
230f002902 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-20 11:01:57 +00:00
Gabriel Adrian Samfira
b7d138d2ac Add notifications for jobs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-19 13:44:24 +00:00
Gabriel Adrian Samfira
5f07bc2d7c Check if producer was registered
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-19 12:40:56 +00:00
Gabriel Adrian Samfira
0c8c6f5668 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-19 12:27:48 +00:00
Gabriel Adrian Samfira
cc9ecf5847 Add more tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-18 19:28:34 +00:00
Gabriel Adrian Samfira
8a79d9e8f9 Add more watcher tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-18 17:45:48 +00:00
Gabriel Adrian Samfira
37f6434ed8 Fix race condition and add some tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-18 16:42:24 +00:00
Gabriel Adrian Samfira
b51683f1ae Add some tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-17 19:42:50 +00:00
Gabriel
a66cbccdd9
Merge pull request #261 from fabi200123/integration-tests
Refactor Integration tests
2024-06-17 13:57:42 +03:00
Fabian Fulga
9d4c0a953c Adding garm test suite 2024-06-17 12:36:00 +03:00
Gabriel Adrian Samfira
6051629810 Add watcher for github creds and endpoints
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-14 20:35:02 +00:00
Gabriel Adrian Samfira
7f9db2e413 Send notify on update controller
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-14 20:24:45 +00:00
Gabriel Adrian Samfira
8d57fc8fa2 Add rudimentary database watcher
Adds a simple database watcher. At this point it's just one process, but
the plan is to allow different implementations that inform the local running
workers of changes that have occured on entities of interest in the database.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-14 19:47:12 +00:00
Gabriel
4c7c9b0e1e
Merge pull request #259 from gabriel-samfira/fix-readme-typos
Fix typos
2024-06-08 12:38:50 +03:00
Gabriel Adrian Samfira
1058c40c43 Fix typos
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-07 18:24:58 +00:00
Gabriel
214cb05072
Merge pull request #256 from gabriel-samfira/move-urls-to-db
Move URLs from default section of config to DB
2024-06-07 13:09:04 +03:00
Gabriel Adrian Samfira
aea328bab9 Remove URLs from sample config
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-07 10:04:34 +00:00
Gabriel Adrian Samfira
37ae7520b8 Update docs
Update the quickstart and the "using garm" sections.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-07 09:27:38 +00:00
Gabriel Adrian Samfira
3992f97d8c Fix tests and make URLs optional in config
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-07 09:27:38 +00:00
Gabriel Adrian Samfira
9748aa47af Move URLs from default section of config to DB
This change moves the callback_url, metadata_url and webhooks_url from
the config to the database. The goal is to move as much as possible from
the config to the DB, in preparation for a potential refactor that will
allow GARM to scale out. This would allow multiple nodes to share a single
source of truth.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-06-07 09:27:24 +00:00
Gabriel
7ee235aeb0
Merge pull request #255 from mercedes-benz/remove_runner_name_lookup_via_job_id
fix: remove unnecessary github api call
2024-06-05 15:05:16 +03:00
Mario Constanti
b4e7dead1c fix: check if runner name is empty and return
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-06-05 13:48:53 +02:00
Mario Constanti
dc74c45317 fix: remove unnecessary github api call
There are only a few cases, where we get a job information from github
where the runner name is not set.

For all this cases we do not need to check github API at all because
these jobs are never ever get scheduled to a runner:

job.Action is:

* queued:
  a queued job is just queued and not scheduled to a runner so we do
  not get a runner name from the GH API
* completed:
  when conclusion=cancelled|failure github never scheduled the job to a
  runner and with that we do not get a runner name from the GH API

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-06-05 12:37:20 +02:00
Gabriel
02ff74bfe8
Merge pull request #254 from mercedes-benz/fix_conclusion_typo
fix: use the american english type of cancelled
2024-06-05 13:10:36 +03:00
Mario Constanti
7adc48c75f fix: use the american english type of cancelled
github is sending job events where conclusion=cancelled is spelled in american english.

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-06-05 11:57:33 +02:00
Gabriel
7538f4add9
Merge pull request #252 from gabriel-samfira/update-readme
Add note about stable release documentation
2024-05-25 09:57:34 +03:00
Gabriel Adrian Samfira
ae80ae0442 Add note about stable release documentation
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-25 06:55:10 +00:00
Gabriel
09f050553c
Merge pull request #251 from gabriel-samfira/update-go-swagger
Update go-swagger and run generate
2024-05-23 14:40:52 +03:00
Gabriel Adrian Samfira
ff6db9bd61 Update go-swagger and run generate
This updates go-swagger to v0.31.0, which no longer panics when used
with golang v1.22+.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-23 10:24:44 +00:00
Gabriel
ab3bef8b41
Merge pull request #249 from mercedes-benz/new_runners_without_default_labels
New runners without default labels
2024-05-22 21:18:57 +03:00
Mario Constanti
debb9696ce docs: document released provider-common version
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-05-22 06:04:22 +02:00
Mario Constanti
27e081eb36 remove required tags during update
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-05-22 06:03:06 +02:00
Mario Constanti
c4f023b6a8 doc: add some notes about default labels
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-05-21 12:06:54 +02:00
Mario Constanti
40cdf5b639 doc: remove self-hosted label from docs
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-05-21 11:55:12 +02:00
Mario Constanti
1d14a26325 feat: garm pools do not force default labels
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-05-21 11:55:12 +02:00
Gabriel
6e416bb494
Merge pull request #246 from gabriel-samfira/remove-duplicate-pool-characteristics-check
Remove check for duplicate pool
2024-05-10 20:31:37 +03:00
Gabriel
45d5f152ce
Merge pull request #247 from gabriel-samfira/add-toc-to-docs
Add TOC
2024-05-10 11:49:19 +03:00
Gabriel Adrian Samfira
f721d74840 Add TOC
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-10 08:48:47 +00:00
Gabriel Adrian Samfira
be4f303b82 Remove check for duplicate pool
This change removes a check that denies the creation of a pool
if the new pool has the same image and flavor set on the same
provider. The reasoning for that check was that if you need to
create another pool with identical settings to an existing one,
you might as well scale up the min-idle-runners on the old one.

This was done when runner groups were not yet added. This in
turn has forced users to alias images with new names in their
provider, leading to terrible UX. In the end, being too
opinionated in this case has caused more harm than good.

Fixes #245

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-10 08:12:44 +00:00
Gabriel
76d45ad83f
Merge pull request #243 from gabriel-samfira/use-db-for-gh-creds
Move github credentials to the database
2024-05-09 19:36:04 +03:00
Gabriel Adrian Samfira
b3e2c584bf Update docs
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-07 21:22:40 +00:00
Gabriel Adrian Samfira
27e74ef277 Add DB migration test
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-07 11:52:26 +00:00
Gabriel
75eb45c97a
Update database/sql/sql.go
Co-authored-by: Mario Constanti <github@constanti.de>
2024-05-07 13:13:16 +03:00
Gabriel Adrian Samfira
8726cb994e Move the name check before tx
No point in making a DB query if we know we don't want to be able to
delete/update the default endpoint.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-05-07 10:07:47 +00:00
Gabriel Adrian Samfira
2a3d524a71 Add more unit tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-29 09:47:26 +00:00
Gabriel Adrian Samfira
2b1414d150 Add some unit tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-28 17:20:40 +00:00
Gabriel Adrian Samfira
402c8b70e2 Use different creds than the default ones
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-27 18:55:30 +00:00
Gabriel Adrian Samfira
349ba1f9e8 Fix nil pointer dereference
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-27 18:17:35 +00:00
Gabriel Adrian Samfira
87943db62c Fix lint and add integration tests logging
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-27 18:10:03 +00:00
Gabriel Adrian Samfira
0128f59344 Add some credentials e2e tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-25 17:38:24 +00:00
Gabriel Adrian Samfira
39a5e14eb1 Add more e2e GH endpoint tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-25 07:45:09 +00:00
Gabriel Adrian Samfira
ccf51053b5 Add github endpoint operations e2e test
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-24 14:54:29 +00:00
Gabriel Adrian Samfira
1256473089 Fetch credentials from DB
Do not rely on the entity object to hold updated or detailed credentials,
fetch them from the DB every time.

This change also ensures that we pass in the user context instead of the
runner context to the DB methods.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-24 13:59:15 +00:00
Gabriel Adrian Samfira
c2b974dfa0 Create clone creds for repo update
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-24 11:39:20 +00:00
Gabriel Adrian Samfira
f5682e6323 Work around actions/runner-images#7210
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-24 11:30:15 +00:00
Gabriel Adrian Samfira
8b5584f083 Add some e2e boilerplate
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-24 11:21:27 +00:00
Gabriel Adrian Samfira
e8ea7117ce Fix tests post-rebase
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:10:51 +00:00
Gabriel Adrian Samfira
eb1456479b Deny deleting the default github.com endpoint
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
208a4eea37 Ensure github endpoint
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
eadbe784b9 Add github credentials API and cli code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
77ecb16166 Add github endpoint API endpoint and CLI code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
257fb0b09a Take into account legacy config
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
4610f83209 List credentials from db
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:37 +00:00
Gabriel Adrian Samfira
9c1ffe8c20 Enforce same endpoint when updating credentials
When updating credentials on an entity, we must ensure that the new credentials
belong to the same endpoint as the entity.

When an entity is created, the endpoint is determined by the credentials that
were used during the create operation. From that point forward the entity is
associated with an endpoint, and that cannot change.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:08:36 +00:00
Gabriel Adrian Samfira
3e60a48ca8 Preload credentials endpoint and remove extra code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:03:25 +00:00
Gabriel Adrian Samfira
032d40f5f9 Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:03:25 +00:00
Gabriel Adrian Samfira
90870c11be Use database for github creds
Add database models that deal with github credentials. This change
adds models for github endpoints (github.com, GHES, etc). This change
also adds code to migrate config credntials to the DB.

Tests need to be fixed and new tests need to be written. This will come
in a later commit.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 14:03:25 +00:00
Gabriel
834c3bb798
Merge pull request #244 from gabriel-samfira/update-dependencies
Update dependencies and tests
2024-04-22 16:02:39 +02:00
Gabriel Adrian Samfira
97d03dd38d Update dependencies and tests
This commit updates the dependencies, vendor files and updates tests
to take into account changes to the DB driver.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-22 13:39:04 +00:00
Gabriel
069bdd8b6b
Merge pull request #242 from gabriel-samfira/some-cleanup
Remove some code, move some code around
2024-04-01 17:57:06 +03:00
Gabriel Adrian Samfira
cb4d56773f Remove some code, move some code around
Remove code that was just wrapping other functions at this point, and
move some code around. We need to get a better idea what is actually
still needed in the pool manager, to begin to refactor it into something
that can scale out.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-04-01 14:52:37 +00:00
Gabriel
9525e013da
Merge pull request #241 from gabriel-samfira/some-cleanup
Slightly simplify code
2024-03-30 20:35:24 +02:00
Gabriel Adrian Samfira
36288c65e6 Slightly simplify code
Change instance DB functions from querying by ID to querying by name. Names
are unique in GARM, so we might as well use the name instead of the ID and
spare ourselves the extra query to get the ID when a qorkflow comes in.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-30 18:22:06 +00:00
Gabriel
9cbb2f867e
Merge pull request #240 from gabriel-samfira/deduplicate-db-code
Deduplicate db code
2024-03-29 20:54:59 +02:00
Gabriel Adrian Samfira
f9f545f060 Remove duplicate code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-29 18:50:04 +00:00
Gabriel Adrian Samfira
9384e37bb1 Fix tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-28 18:23:49 +00:00
Gabriel Adrian Samfira
0152b21529 Implement some common logic for pool creation
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-28 10:09:20 +00:00
Gabriel
72501aee0f
Merge pull request #239 from gabriel-samfira/fix-nil-pointer-cmd-pool
Fix potential nil pointer dereference in cli
2024-03-28 12:08:49 +02:00
Gabriel Adrian Samfira
15129c8c9f Fix potential nil pointer dereference in cli
This change fixes a potential nil pointer dereference when a call to
create a pool, fails.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-28 10:01:50 +00:00
Gabriel
18bb126c0d
Merge pull request #238 from cloudbase/fix-nil-pointer-dereference
Check for nil pointer before dereferencing
2024-03-26 16:44:18 +02:00
Gabriel Adrian Samfira
e2eb8f719b
Check for nil pointer before dereferencing
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-26 16:43:09 +02:00
Gabriel
bb67ae5afe
Merge pull request #237 from gabriel-samfira/fix-jit-config-empty-group
Fix JIT config with empty runner group name
2024-03-25 20:59:56 +02:00
Gabriel Adrian Samfira
39f1be5512 Fix JIT config with empty runner group name
When no runner group is set, do not attempt to resolve the runner group.
Looking for an empty runner group will just return a not found error, which
will make GARM fall back to registration token.

This change fixes that.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-25 18:53:53 +00:00
Gabriel
90dd92d27c
Merge pull request #235 from gabriel-samfira/refactor-internal-gh-client
Refactor internal gh client
2024-03-18 20:12:53 +02:00
Gabriel Adrian Samfira
f0080047a3 Remove superfluous function
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-18 10:56:49 +00:00
Gabriel Adrian Samfira
56da6a4437 Slightly better UX when dealing with webhooks
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-18 10:19:16 +00:00
Gabriel Adrian Samfira
9259f84e56 Fix getting webhook URL info
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-18 09:53:34 +00:00
Gabriel Adrian Samfira
cfb68f8928 Check webhook secret for entity
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-18 09:39:07 +00:00
Gabriel Adrian Samfira
e3ffc153d2 simplify switch statement
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 18:08:46 +00:00
Gabriel Adrian Samfira
bef8f30d63 Fix lint
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 11:13:14 +00:00
Gabriel Adrian Samfira
fa75ecfa8e Dedupe more code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 10:59:09 +00:00
Gabriel Adrian Samfira
b550d0c5b9 remove extra function
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 10:28:35 +00:00
Gabriel Adrian Samfira
1734e6f87c Deduplicate code
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 10:21:41 +00:00
Gabriel Adrian Samfira
234f71d9d1 Rename PoolType to GithubEntityType
We'll use GithubEntityType throughout the codebase to determine the
type of operation that is about to take place, so this won't belimited
to determining only pool type. We'll also use this to dedupe the label
scope as well.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 06:58:03 +00:00
Gabriel
2c217f0479
Merge pull request #234 from gabriel-samfira/add-oci-provider
Add OCI to provider list
2024-03-17 08:03:55 +02:00
Gabriel Adrian Samfira
e7834820c3 Add OCI to provider list
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-17 06:03:06 +00:00
Gabriel
6bfcddca75
Merge pull request #233 from gabriel-samfira/add-balancing-strategy
Add pool balancing strategy
2024-03-15 23:40:12 +02:00
Gabriel Adrian Samfira
206fe42c73 Remove unused code, update test
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-15 15:48:53 +00:00
Gabriel Adrian Samfira
ac29af6eff Add some unit tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-15 14:35:23 +00:00
Gabriel Adrian Samfira
d7ea80a657 Remove log message
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-15 08:12:16 +00:00
Gabriel Adrian Samfira
cdfda0321a Fix balancer type validation
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-15 07:26:04 +00:00
Gabriel Adrian Samfira
b58555bc10 Fix missing info in pool list
Without preloading the entity we're listing pools for, we don't get that
info when listing pools for a repo/org/enterprise.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-14 20:19:54 +00:00
Gabriel Adrian Samfira
ce3c917ae5 Add pool balancing strategy
This change adds the ability to specify the pool balancing strategy to
use when processing queued jobs. Before this change, GARM would round-robin
through all pools that matched the set of tags requested by queued jobs.

When round-robin (default) is used for an entity (repo, org or enterprise)
and you have 2 pools defined for that entity with a common set of tags that
match 10 jobs (for example), then those jobs would trigger the creation of
a new runner in each of the two pools in turn. Job 1 would go to pool 1,
job 2 would go to pool 2, job 3 to pool 1, job 4 to pool 2 and so on.

When "stack" is used, those same 10 jobs would trigger the creation of a
new runner in the pool with the highest priority, every time.

In both cases, if a pool is full, the next one would be tried automatically.

For the stack case, this would mean that if pool 2 had a priority of 10 and
pool 1 would have a priority of 5, pool 2 would be saturated first, then
pool 1.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-14 20:04:34 +00:00
Gabriel
569d512819
Merge pull request #232 from gabriel-samfira/add-job-details
Add job info in runner list
2024-03-12 15:14:07 +02:00
Gabriel Adrian Samfira
7d33e0f0cf Add job info in runner list
This change adds information about the job a runner is currently handling.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-11 15:46:18 +00:00
Gabriel
321126629a
Merge pull request #231 from gabriel-samfira/bypass-gh-unauthorized
Allow bypassing Unauthorized error when deleting runner
2024-03-10 17:51:39 +02:00
Gabriel Adrian Samfira
9a6770c3a3 Allow bypassing Unauthorized error when deleting runner
This change allows users to bypass GitHub Unauthorized errors when removing
github runners. This means that removing runners will now be possible even
if the pool manager is stopped.

There is a new flag added to the runner rm command and to the API that
tells GARM to bypass pool being stopped and any 401 error returned by
GitHub.

This means you will be able to remove the runners from garm and your
provider, but will mean that the runner will still exist in github as
"offline" if the credentials are not updated or the runner manually removed.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-10 15:21:39 +00:00
Gabriel
df72c4917e
Merge pull request #229 from gabriel-samfira/add-toc
Add ToC to using_garm.md
2024-03-05 09:52:37 +02:00
Gabriel Adrian Samfira
73a2690d45 Add ToC to using_garm.md
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-05 07:52:01 +00:00
Gabriel
1b11c682c1
Merge pull request #228 from gabriel-samfira/add-github-app-support
Add GitHub App support
2024-03-04 09:46:10 +02:00
Gabriel Adrian Samfira
d734286296 Add some tests
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-02 20:42:36 +00:00
Gabriel Adrian Samfira
4733cac526 Replace errors.Wrap calls
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-02 19:07:06 +00:00
Gabriel Adrian Samfira
4668461603 Expose the credential type through the API
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-02 17:04:27 +00:00
Gabriel Adrian Samfira
cbb2134f0e Add GitHub App support
This change adds the ability to use GitHub Apps to authenticate against the
GitHub API. This gives us a larger quota for API requests (15k vs 5k for PATs).

Also, each GitHub App has its own quota, whereas PATs share the same user quota.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-03-01 19:47:50 +00:00
Gabriel
2ea6bb9490
Merge pull request #225 from gabriel-samfira/fix-variables
Fix variable name
2024-02-26 21:06:14 +02:00
Gabriel Adrian Samfira
b5e3552776 Fix variable name
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 19:04:48 +00:00
Gabriel
d3f6c40258
Merge pull request #224 from gabriel-samfira/simplify-job
simplify integration test job
2024-02-26 19:58:40 +02:00
Gabriel Adrian Samfira
111b93f062 simplify integration test job
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 17:58:04 +00:00
Gabriel
c233559d3b
Merge pull request #223 from gabriel-samfira/use-user-service
Use user service
2024-02-26 19:41:51 +02:00
Gabriel Adrian Samfira
43b3db5c0c Use user service
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 17:41:04 +00:00
Gabriel
72c5364537
Merge pull request #222 from gabriel-samfira/add-scripts-and-service
Add script and service template
2024-02-26 18:48:47 +02:00
Gabriel Adrian Samfira
a17cd577e0 Add script and service template
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 16:48:22 +00:00
Gabriel
5c49bc79ae
Merge pull request #221 from gabriel-samfira/switch-to-apg
Switch to apg for password gen
2024-02-26 18:45:16 +02:00
Gabriel Adrian Samfira
00fd7c1204 Switch to apg for password gen
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 16:44:47 +00:00
Gabriel
9d21bd6b51
Merge pull request #220 from gabriel-samfira/fix-integration-tests
Install dependencies and set RUN_USER
2024-02-26 18:39:18 +02:00
Gabriel Adrian Samfira
b9b185d1c1 Install dependencies and set RUN_USER
Install make dependencies and default to current user

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 16:38:27 +00:00
Gabriel
8728051c40
Merge pull request #219 from gabriel-samfira/augment-tests
Allow integration tests to run locally
2024-02-26 18:32:00 +02:00
Gabriel Adrian Samfira
b4dde6a839 Allow integration tests to run locally
This change adds the ability to run integration tests locally. You will
still need a number of environment variables set, including a github PAT.

Details on how to use this will come in a subsequent commit.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-26 16:28:07 +00:00
Gabriel
cffb4f23d4
Merge pull request #218 from mercedes-benz/introduce_golangci_config
Introduce golangci config and `make help`
2024-02-22 19:39:49 +02:00
Mario Constanti
d332e7a8ca fix: gocritic linter finding
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:40:15 +01:00
Mario Constanti
4c81c16505 fix: goconst linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:39:02 +01:00
Mario Constanti
9e7ac60c09 fix: gosec linter finding
we have to keep crypto/sha1 as github is still using it

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:34:12 +01:00
Mario Constanti
fd0550eb7f fix: godoc linter findings (TODO comments)
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:33:19 +01:00
Mario Constanti
ee3a670456 fix: var-naming linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:28:39 +01:00
Mario Constanti
7221812dfa fix: remove unused cobra args
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 17:20:05 +01:00
Mario Constanti
4409beb18a fix: G601: Implicit memory aliasing in for loop
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 16:57:26 +01:00
Mario Constanti
60dbf97ba4 fix: ignore testing secret
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 16:55:42 +01:00
Mario Constanti
9f5c38ef2d fix: unused-parameter linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 16:54:38 +01:00
Mario Constanti
73eb21438a fix: run make lint same way as in ci
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 16:54:20 +01:00
Mario Constanti
b8a9b6c89b fix: ignore testing package typechecks
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
c137f9b662 fix: gocritic linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
742ebabfc3 fix: unneded type conversion
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
b27f523259 fix: ifElseChain linter finding
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
f4e51493f3 fix: var-naming linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
f9e41f11d1 fix: gosec linter finding
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
cbe8f09412 fix: run make lint-fix
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
3fd09f6dcd fix: assignOp linter finding
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
c89deaeca7 fix: ifElseChain linter finding
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
55fe81fe32 fix: gosec linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
09e25ca8b1 fix: gosec linter finding - memory aliasing
G601: Implicit memory aliasing in for loop

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
9f405e0e8f fix: ifElseChain linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
b0e3f78fbb fix: godoc linter warnings (TODOs)
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
acc17eafcd fix: receiver-naming linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
f6404456b9 fix: indent-error-flow linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
6065fb2e3b fix: increment-decrement linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
e664639e98 fix: var-declaration linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
e5ed45c258 fix: unnecessary conversion linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
0ab86a7e51 fix: unused-parameter linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
3b9f8b555b fix: var-naming linter findings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
bd0b27ab10 fix: gci section warnings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
8fc001f5f6 fix: misspell linter warnings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
b3854eaf18 fix: whitespace linter warnings
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
023652d76d fix: make build as PHONY target
without build as PHONY target, nothing will happen once the build
directory got created.

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Mario Constanti
9ea2a312d2 feat: introduce golangci config and help in make
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 15:06:53 +01:00
Gabriel
dd6f1e48b8
Merge pull request #217 from mercedes-benz/add_counter_metrics
extend metrics for github and provider executions
2024-02-22 09:35:41 +02:00
Mario Constanti
d68cc3bf05 fix: add missing metrics for few gh api callS
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-22 05:57:42 +01:00
Mario Constanti
6cb6350602 doc: document new operations/errors metrics
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-21 14:41:08 +01:00
Mario Constanti
9716b1d8c9 fix: align metric names
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-21 14:29:43 +01:00
Mario Constanti
b36b5137b6 feat: count github api calls
introduce metrics counter for github api calls

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-21 14:22:45 +01:00
Mario Constanti
0faf0927bc feat: count external provider operations
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-21 14:21:41 +01:00
Gabriel
e108140eb6
Merge pull request #216 from mercedes-benz/extended_metrics
chore: refactor metrics endpoint
2024-02-20 17:46:22 +02:00
Mario Constanti
b1cbfac08a fix: switch to context.Background() for adminctx
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 16:42:10 +01:00
Mario Constanti
2a3e4d6563 fix: pass context.TODO by getting admin context
fix linter warnings

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 16:39:52 +01:00
Mario Constanti
0a53b8f6d8 fix: stop metrics collector ticker on ctx.Done
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 14:57:32 +01:00
Mario Constanti
17d74dfbf0 chore: rework prometheus metrics registration
fail if metric registration panics

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 14:27:27 +01:00
Mario Constanti
3e025dda2f feat: define a default duration for metrics update
Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 10:23:48 +01:00
Mario Constanti
97f172eb51 fix: improve metrics collection loop
by adding the context from main and make auth.GetAdminContext accepting a
context we are now able to stop the metrics collection loop once the
context is canceled

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-20 06:33:21 +01:00
Mario Constanti
1d8d9459eb chore: refactor metrics endpoint
refactoring is needed to make the metrics package usable from within the
runner package for further metrics.

This change also makes the metric-collector independent from requests to
the /metrics endpoint

Signed-off-by: Mario Constanti <mario.constanti@mercedes-benz.com>
2024-02-19 16:22:32 +01:00
Gabriel
f68cf98d67
Merge pull request #215 from jepio/fix-static-docker
Dockerfile: Build actually static binaries
2024-02-16 10:39:59 +02:00
Jeremi Piotrowski
b4644ca3c8 Dockerfile: Build actually static binaries
Without '-linkmode external' some of the produced binaries were not actually
static. /bin/garm was fine but providers would fail with "exit code 127" when
executed. Unpacking the container image and running the binaries in strace
showed that they were accessing the musl dynamic linker.

Signed-off-by: Jeremi Piotrowski <jpiotrowski@microsoft.com>
2024-02-16 09:31:04 +01:00
Gabriel
e575053f7c
Merge pull request #210 from gabriel-samfira/add-new-providers
Add new providers
2024-02-12 21:16:52 +02:00
Gabriel Adrian Samfira
342ed8e990 Add new providers
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 19:16:12 +00:00
Gabriel
96208bb3c2
Merge pull request #209 from gabriel-samfira/fix-typos
Fix typos in garm-cli
2024-02-12 12:06:52 +02:00
Gabriel Adrian Samfira
eb729320f9 Fix typos in garm-cli
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 10:05:23 +00:00
Gabriel
6ca50dc4b2
Merge pull request #208 from gabriel-samfira/update-readme
Add GCP to the list of providers
2024-02-12 11:55:50 +02:00
Gabriel Adrian Samfira
803f7afd70 Add GCP to the list of providers
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 09:55:22 +00:00
Gabriel
3b9e822ee0
Merge pull request #207 from gabriel-samfira/update-readme
Update readme
2024-02-12 11:04:33 +02:00
Gabriel Adrian Samfira
8efdcba359 Update README
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 09:01:13 +00:00
Gabriel Adrian Samfira
d4a9a821cf Add some more info
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 08:44:26 +00:00
Gabriel Adrian Samfira
1ffa562581 Add using garm doc
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-12 01:06:25 +00:00
Gabriel Adrian Samfira
d17629efd4 Add logging section info
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-11 12:47:19 +00:00
Gabriel Adrian Samfira
53264528ee Add Equinix and EC2 in the README
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-02-11 12:28:49 +00:00
Gabriel
7c44b8125a
Merge pull request #206 from gabriel-samfira/more-strict-token-checks
More strict instance token checks
2024-01-30 13:57:14 +02:00
Gabriel Adrian Samfira
9031a4029e More strict instance token checks
This change invalidates tokens based on more parameters. Tokens that were
generated for previous attempts of spinning up an instance will be invalidates.

Also, only instances that are in Running or Creating will be able to authenticate.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-30 11:07:55 +00:00
Gabriel
23c9ed6b6d
Merge pull request #205 from gabriel-samfira/add-some-logging
Add some logging
2024-01-30 11:41:53 +02:00
Gabriel Adrian Samfira
43b96c543d Add some logging
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-30 09:37:26 +00:00
Gabriel
8e0456c83a
Merge pull request #203 from gabriel-samfira/small-fixes
Small adjustments
2024-01-12 22:07:28 +02:00
Gabriel Adrian Samfira
5b735eaaf4 Small adjustments
This change increases the tools refresh interval to 5 minutes, cleans
up the websocket code a bit, augments the error message that may be returned
when trying to delete a runner in an invalid state and removes a log message
that does not add much value.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-12 19:53:27 +00:00
Gabriel
523237ca18
Merge pull request #202 from gabriel-samfira/cleanup-websocket-code
Fix log streamer and cleanup code
2024-01-06 16:22:09 +02:00
Gabriel Adrian Samfira
4d7fcbe23a Safely close the quit channel
Prevent accidental closure of an already closed channel.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-06 14:15:52 +00:00
Gabriel Adrian Samfira
70bfff96e0 Fix log streamer and cleanup code
I accidentally disabled the log streamer when I moved the config options
to their own section. This change fixes that.

This change also adds some safety checks and locking when cleaning up stale
clients. The websocket hub Write() function now copies the message before
sending it on the channel to the clients.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-06 14:05:38 +00:00
Gabriel
0aaeebde28
Merge pull request #201 from gabriel-samfira/switch-to-slog
Switch to slog
2024-01-06 03:04:09 +02:00
Gabriel Adrian Samfira
d44d64dbfd Use log_file from logging config
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-06 00:32:39 +00:00
Gabriel Adrian Samfira
61e97f0896 Append pool_type and pool_mgr info to logs
Pool managers will have 2 fields identifying which manager generated
the log line.

In the future, we will add tracking ids in various cases, allowing
us to track down issues faster.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-06 00:21:50 +00:00
Gabriel Adrian Samfira
e441b6ce89 Switch to log/slog
This change switches GARM to the new structured logging standard
library. This will allow us to set log levels and reduce some of
the log spam.

Given that we introduced new knobs to tweak logging, the number of
config options for logging now warrants it's own section.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-05 23:46:40 +00:00
Gabriel
f72e97209f
Merge pull request #200 from gabriel-samfira/add-systeminfo-callback
Add system-info instance callback
2024-01-04 17:38:02 +02:00
Gabriel Adrian Samfira
2a5e2409b2 Add system-info instance callback
Allow runners to update their own system information. Runners can now send
back os_name, os_version and agent_id back as part of a POST to
CALLBACK_URL/system-info/.

The goal is to get better info in regard to the actual OS that's running
and to move the agent_id from the status updates to the system-info callback.

The status updates should be used only to send back info about the status of
the installation process.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
2024-01-04 15:23:43 +00:00
1970 changed files with 321690 additions and 69526 deletions

11
.github/dependabot.yml vendored Normal file
View file

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"

View file

@ -1,14 +1,16 @@
name: "Build GARM images"
name: "Build and push GARM images"
on:
workflow_dispatch:
workflow_call:
inputs:
push_to_project:
description: "Project to build images for"
required: true
required: false
type: string
default: "ghcr.io/cloudbase"
ref:
description: "Ref to build"
required: true
required: false
type: string
default: "main"
permissions:
@ -19,10 +21,10 @@ jobs:
permissions:
packages: write
name: "Build GARM images"
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: src/github.com/cloudbase/garm
fetch-depth: 0
@ -37,13 +39,23 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
- name: Build and push image
env:
IMAGE_REGISTRY: ${{ inputs.push_to_project }}
GH_REF: ${{ inputs.ref }}
working-directory: src/github.com/cloudbase/garm
run: |
cd src/github.com/cloudbase/garm
VERSION=$(git describe --tags --match='v[0-9]*' --always ${{ github.event.inputs.ref }})
if [ "$GH_REF" == "main" ]; then
IMAGE_TAG="nightly"
else
IMAGE_TAG=$(git describe --tags --match='v[0-9]*' --always ${GH_REF})
fi
docker buildx build \
--provenance=false \
--platform linux/amd64,linux/arm64 \
--build-arg="GARM_REF=${{ github.event.inputs.ref }}" \
-t ${{ github.event.inputs.push_to_project }}/garm:"${VERSION}" \
--push .
--label "org.opencontainers.image.source=https://github.com/cloudbase/garm/tree/${GH_REF}" \
--label "org.opencontainers.image.description=GARM ${GH_REF}" \
--label "org.opencontainers.image.licenses=Apache 2.0" \
--build-arg="GARM_REF=${GH_REF}" \
-t ${IMAGE_REGISTRY}/garm:"${IMAGE_TAG}" \
--push .

View file

@ -4,9 +4,11 @@ on:
push:
branches:
- main
- 'release/**'
pull_request:
branches:
- main
- 'release/**'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
@ -17,23 +19,22 @@ permissions: {}
jobs:
linters:
name: Linters
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libbtrfs-dev build-essential
sudo apt-get install -y libbtrfs-dev build-essential apg jq
- uses: actions/setup-go@v3
with:
go-version: 'stable'
- uses: actions/checkout@v3
- uses: golangci/golangci-lint-action@v3
- uses: actions/setup-go@v5
with:
skip-cache: true
args: --timeout=8m --build-tags testing
go-version-file: go.mod
- name: make lint
run: make golangci-lint && GOLANGCI_LINT_EXTRA_ARGS="--timeout=8m --build-tags=testing,integration" make lint
- name: Verify go vendor, go modules and gofmt
run: |
sudo apt-get install -y jq
@ -43,15 +44,39 @@ jobs:
runs-on: ubuntu-latest
needs: [linters]
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libbtrfs-dev build-essential apg jq default-jre
- uses: actions/setup-node@v4
with:
node-version: '>=v24.5.0'
- name: Set up openapi-generator-cli
run: |
mkdir -p $HOME/openapi-generator
cd $HOME/openapi-generator
npm install @openapitools/openapi-generator-cli
echo "$HOME/openapi-generator/node_modules/.bin" >> $GITHUB_PATH
- name: Checkout
uses: actions/checkout@v3
- name: Setup Golang
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version-file: go.mod
- run: go version
- name: Run go generate
run: |
GOTOOLCHAIN=go1.24.6 make generate
- name: Run GARM Go Tests
run: make go-test
- name: Run web UI tests
run: |
make webui-test

View file

@ -6,10 +6,10 @@ on:
jobs:
integration-tests:
runs-on: ubuntu-latest
runs-on: ubuntu-noble-garm
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Golang
uses: actions/setup-go@v3
@ -17,30 +17,53 @@ jobs:
go-version-file: go.mod
- name: Setup LXD
uses: canonical/setup-lxd@v0.1.1
- name: Build GARM
run: make build
- name: Set up ngrok
id: ngrok
uses: gabriel-samfira/ngrok-tunnel-action@v1.1
uses: canonical/setup-lxd@main
with:
ngrok_authtoken: ${{ secrets.NGROK_AUTH_TOKEN }}
port: 9997
tunnel_type: http
channel: latest/stable
- name: Setup GARM
run: ./test/integration/scripts/setup-garm.sh
env:
GH_OAUTH_TOKEN: ${{ secrets.GH_OAUTH_TOKEN }}
CREDENTIALS_NAME: test-garm-creds
GARM_BASE_URL: ${{ steps.ngrok.outputs.tunnel-url }}
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get -qq update && sudo apt-get -qq install -y apg coreutils make jq build-essential libsqlite3-dev libsqlite3-0
- name: Set up tunnel
shell: bash
run: |
mkdir -p /home/runner/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > /home/runner/.ssh/ssh_key
sudo chown -R runner:runner /home/runner/.ssh
sudo chmod 500 /home/runner/.ssh
sudo chmod 400 /home/runner/.ssh/ssh_key
SUBDOMAIN=$(apg -a 0 -M l -m 12 -n 1)
echo "::add-mask::$SUBDOMAIN"
BASE_URL="${{ secrets.TUNNEL_BASE_URL }}"
GARM_BASE_URL="https://$SUBDOMAIN.$BASE_URL"
echo "::add-mask::$GARM_BASE_URL"
echo "GARM_BASE_URL=$GARM_BASE_URL" >> $GITHUB_ENV
cat <<EOF | sudo tee /etc/systemd/system/garm-tunnel.service
[Unit]
Description=GARM tunnel
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ssh -q -i /home/runner/.ssh/ssh_key -N -n -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -R $SUBDOMAIN:80:127.0.0.1:9997 $BASE_URL
Restart=always
User=runner
[Install]
WantedBy=default.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable garm-tunnel
sudo systemctl start garm-tunnel
- name: Generate secrets
run: |
sudo apt-get -qq update && sudo apt-get -qq install -y apg
GARM_PASSWORD=$(apg -n1 -m32)
REPO_WEBHOOK_SECRET=$(apg -n1 -m32)
ORG_WEBHOOK_SECRET=$(apg -n1 -m32)
@ -52,6 +75,7 @@ jobs:
echo "GARM_PASSWORD=$GARM_PASSWORD" >> $GITHUB_ENV
echo "REPO_WEBHOOK_SECRET=$REPO_WEBHOOK_SECRET" >> $GITHUB_ENV
echo "ORG_WEBHOOK_SECRET=$ORG_WEBHOOK_SECRET" >> $GITHUB_ENV
echo "GARM_CHECKOUT_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV
- name: Create logs directory
if: always()
@ -61,24 +85,25 @@ jobs:
run: |
set -o pipefail
set -o errexit
go run ./test/integration/main.go 2>&1 | tee /artifacts-logs/e2e.log
make integration 2>&1
env:
GARM_BASE_URL: ${{ steps.ngrok.outputs.tunnel-url }}
ORG_NAME: gsamfira
REPO_NAME: garm-testing
CREDENTIALS_NAME: test-garm-creds
WORKFLOW_FILE_NAME: test.yml
GH_TOKEN: ${{ secrets.GH_OAUTH_TOKEN }}
LXD_REMOTE_SERVER: ${{ secrets.LXD_REMOTE_SERVER }}
- name: Show GARM logs
if: always()
run: |
sudo systemctl status garm
sudo journalctl -u garm --no-pager 2>&1 | tee /artifacts-logs/garm.log
sudo systemctl status garm@runner || true
sudo journalctl --no-pager 2>&1 > /artifacts-logs/system.log
sudo journalctl -u garm@runner --no-pager 2>&1 > /artifacts-logs/garm.log
- name: Upload GARM and e2e logs
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: garm-logs
path: /artifacts-logs
@ -89,11 +114,9 @@ jobs:
set -o pipefail
set -o errexit
sudo systemctl stop garm
go run ./test/integration/gh_cleanup/main.go
sudo systemctl stop garm@runner || true
go run ./test/integration/gh_cleanup/main.go || true
env:
GARM_BASE_URL: ${{ steps.ngrok.outputs.tunnel-url }}
ORG_NAME: gsamfira
REPO_NAME: garm-testing
GH_TOKEN: ${{ secrets.GH_OAUTH_TOKEN }}

19
.github/workflows/trigger-manual.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: Manual build of GARM images
on:
workflow_dispatch:
inputs:
push_to_project:
description: "Project to build images for"
required: true
default: "ghcr.io/cloudbase"
ref:
description: "Ref to build"
required: true
default: "main"
jobs:
call-build-and-push:
uses: ./.github/workflows/build-and-push.yml
with:
push_to_project: ${{ inputs.push_to_project }}
ref: ${{ inputs.ref }}

10
.github/workflows/trigger-nightly.yml vendored Normal file
View file

@ -0,0 +1,10 @@
name: Nightly build of GARM images
on:
schedule:
- cron: "0 2 * * *"
jobs:
call-build-and-push:
uses: ./.github/workflows/build-and-push.yml
with:
ref: "main"

6
.gitignore vendored
View file

@ -19,3 +19,9 @@ bin/
cmd/temp
build/
release/
node_modules/
.svelte-kit/
debug.html
git_push.sh
webapp/src/lib/api/generated/docs
.env

44
.golangci.yml Normal file
View file

@ -0,0 +1,44 @@
# SPDX-License-Identifier: MIT
linters:
disable-all: true
fast: false
enable:
- gci
- goconst
- gocritic
- gocyclo
- gofmt
- gofumpt
- goimports
- godox
- govet
- gosec
- gosimple
- importas
- ineffassign
- loggercheck
- misspell
- nakedret
- nilerr
- predeclared
- promlinter
- revive
- staticcheck
- unconvert
- unused
- wastedassign
- whitespace
linters-settings:
gci:
sections:
- standard
- default
- prefix(github.com/cloudbase/garm)
goimports:
local-prefixes: github.com/cloudbase/garm
gosec:
excludes:
- G115

27
.mockery.yaml Normal file
View file

@ -0,0 +1,27 @@
with-expecter: true
dir: "mocks"
mockname: "{{ .InterfaceName }}"
outpkg: "mocks"
filename: "{{ .InterfaceName }}.go"
# V3 compatibility settings
resolve-type-alias: false
disable-version-string: true
issue-845-fix: true
packages:
# Database store interfaces
github.com/cloudbase/garm/database/common:
interfaces:
Store:
config:
dir: "{{ .InterfaceDir }}/mocks"
# Runner interfaces
github.com/cloudbase/garm/runner:
interfaces:
PoolManagerController:
config:
dir: "{{ .InterfaceDir }}/mocks"
# Runner common interfaces (generate all interfaces in this package)
github.com/cloudbase/garm/runner/common:
config:
dir: "{{ .InterfaceDir }}/mocks"
all: true

View file

@ -3,36 +3,75 @@ ARG GARM_REF
LABEL stage=builder
RUN apk add musl-dev gcc libtool m4 autoconf g++ make libblkid util-linux-dev git linux-headers
RUN git config --global --add safe.directory /build
RUN apk add --no-cache musl-dev gcc libtool m4 autoconf g++ make libblkid util-linux-dev git linux-headers upx curl jq
RUN git config --global --add safe.directory /build && git config --global --add advice.detachedHead false
RUN echo ${GARM_REF}
ADD . /build/garm
RUN cd /build/garm && git checkout ${GARM_REF}
RUN git clone https://github.com/cloudbase/garm-provider-azure /build/garm-provider-azure
RUN git clone https://github.com/cloudbase/garm-provider-openstack /build/garm-provider-openstack
RUN git clone https://github.com/cloudbase/garm-provider-lxd /build/garm-provider-lxd
RUN git clone https://github.com/cloudbase/garm-provider-incus /build/garm-provider-incus
RUN git clone https://github.com/mercedes-benz/garm-provider-k8s /build/garm-provider-k8s
RUN cd /build/garm && go build -o /bin/garm \
-tags osusergo,netgo,sqlite_omit_load_extension \
-ldflags "-extldflags '-static' -s -w -X main.Version=$(git describe --tags --match='v[0-9]*' --dirty --always)" \
/build/garm/cmd/garm
RUN mkdir -p /opt/garm/providers.d
RUN cd /build/garm-provider-azure && go build -ldflags="-extldflags '-static' -s -w" -o /opt/garm/providers.d/garm-provider-azure .
RUN cd /build/garm-provider-openstack && go build -ldflags="-extldflags '-static' -s -w" -o /opt/garm/providers.d/garm-provider-openstack .
RUN cd /build/garm-provider-lxd && go build -ldflags="-extldflags '-static' -s -w" -o /opt/garm/providers.d/garm-provider-lxd .
RUN cd /build/garm-provider-incus && go build -ldflags="-extldflags '-static' -s -w" -o /opt/garm/providers.d/garm-provider-incus .
RUN cd /build/garm-provider-k8s/cmd/garm-provider-k8s && go build -ldflags="-extldflags '-static' -s -w" -o /opt/garm/providers.d/garm-provider-k8s .
RUN git -C /build/garm checkout ${GARM_REF}
RUN cd /build/garm \
&& go build -o /bin/garm \
-tags osusergo,netgo,sqlite_omit_load_extension \
-ldflags "-linkmode external -extldflags '-static' -s -w -X github.com/cloudbase/garm/util/appdefaults.Version=$(git describe --tags --match='v[0-9]*' --dirty --always)" \
/build/garm/cmd/garm && upx /bin/garm
RUN cd /build/garm/cmd/garm-cli \
&& go build -o /bin/garm-cli \
-tags osusergo,netgo,sqlite_omit_load_extension \
-ldflags "-linkmode external -extldflags '-static' -s -w -X github.com/cloudbase/garm/util/appdefaults.Version=$(git describe --tags --match='v[0-9]*' --dirty --always)" \
. && upx /bin/garm-cli
RUN set -ex; \
mkdir -p /opt/garm/providers.d; \
for repo in \
cloudbase/garm-provider-azure \
cloudbase/garm-provider-openstack \
cloudbase/garm-provider-lxd \
cloudbase/garm-provider-incus \
cloudbase/garm-provider-aws \
cloudbase/garm-provider-gcp \
cloudbase/garm-provider-equinix \
flatcar/garm-provider-linode \
mercedes-benz/garm-provider-k8s; \
do \
export PROVIDER_NAME="$(basename $repo)"; \
export PROVIDER_SUBDIR=""; \
if [ "$GARM_REF" == "main" ]; then \
export PROVIDER_REF="main"; \
else \
export PROVIDER_REF="$(curl -s -L https://api.github.com/repos/$repo/releases/latest | jq -r '.tag_name')"; \
fi; \
git clone --branch "$PROVIDER_REF" "https://github.com/$repo" "/build/$PROVIDER_NAME"; \
case $PROVIDER_NAME in \
"garm-provider-k8s") \
export PROVIDER_SUBDIR="cmd/garm-provider-k8s"; \
export PROVIDER_LDFLAGS="-linkmode external -extldflags \"-static\" -s -w"; \
;; \
"garm-provider-linode") \
export PROVIDER_LDFLAGS="-linkmode external -extldflags \"-static\" -s -w"; \
;; \
*) \
export PROVIDER_VERSION=$(git -C /build/$PROVIDER_NAME describe --tags --match='v[0-9]*' --dirty --always); \
export PROVIDER_LDFLAGS="-linkmode external -extldflags \"-static\" -s -w -X main.Version=$PROVIDER_VERSION"; \
;; \
esac; \
cd "/build/$PROVIDER_NAME/$PROVIDER_SUBDIR" \
&& go build -ldflags="$PROVIDER_LDFLAGS" -o /opt/garm/providers.d/$PROVIDER_NAME . \
&& upx /opt/garm/providers.d/$PROVIDER_NAME; \
done
FROM scratch
FROM busybox
COPY --from=builder /bin/garm /bin/garm
COPY --from=builder /bin/garm-cli /bin/garm-cli
COPY --from=builder /opt/garm/providers.d/garm-provider-openstack /opt/garm/providers.d/garm-provider-openstack
COPY --from=builder /opt/garm/providers.d/garm-provider-lxd /opt/garm/providers.d/garm-provider-lxd
COPY --from=builder /opt/garm/providers.d/garm-provider-incus /opt/garm/providers.d/garm-provider-incus
COPY --from=builder /opt/garm/providers.d/garm-provider-k8s /opt/garm/providers.d/garm-provider-k8s
COPY --from=builder /opt/garm/providers.d/garm-provider-azure /opt/garm/providers.d/garm-provider-azure
COPY --from=builder /opt/garm/providers.d/garm-provider-aws /opt/garm/providers.d/garm-provider-aws
COPY --from=builder /opt/garm/providers.d/garm-provider-gcp /opt/garm/providers.d/garm-provider-gcp
COPY --from=builder /opt/garm/providers.d/garm-provider-equinix /opt/garm/providers.d/garm-provider-equinix
COPY --from=builder /opt/garm/providers.d/garm-provider-k8s /opt/garm/providers.d/garm-provider-k8s
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/bin/garm", "-config", "/etc/garm/config.toml"]

145
Makefile
View file

@ -1,62 +1,139 @@
SHELL := bash
SHELL := /bin/bash
export SHELLOPTS:=$(if $(SHELLOPTS),$(SHELLOPTS):)pipefail:errexit
.ONESHELL:
GEN_PASSWORD=$(shell (/usr/bin/apg -n1 -m32))
IMAGE_TAG = garm-build
USER_ID=$(shell ((docker --version | grep -q podman) && echo "0" || id -u))
USER_GROUP=$(shell ((docker --version | grep -q podman) && echo "0" || id -g))
IMAGE_BUILDER=$(shell (which docker || which podman))
IS_PODMAN=$(shell (($(IMAGE_BUILDER) --version | grep -q podman) && echo "yes" || echo "no"))
USER_ID=$(if $(filter yes,$(IS_PODMAN)),0,$(shell id -u))
USER_GROUP=$(if $(filter yes,$(IS_PODMAN)),0,$(shell id -g))
ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
GOPATH ?= $(shell go env GOPATH)
VERSION ?= $(shell git describe --tags --match='v[0-9]*' --dirty --always)
GARM_REF ?= $(shell git rev-parse --abbrev-ref HEAD)
GO ?= go
export GARM_PASSWORD ?= ${GEN_PASSWORD}
export REPO_WEBHOOK_SECRET = ${GEN_PASSWORD}
export ORG_WEBHOOK_SECRET = ${GEN_PASSWORD}
export CREDENTIALS_NAME ?= test-garm-creds
export WORKFLOW_FILE_NAME ?= test.yml
export GARM_ADMIN_USERNAME ?= admin
ifeq ($(IS_PODMAN),yes)
EXTRA_ARGS := -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
endif
.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
default: build
##@ Build
.PHONY : build-static test install-lint-deps lint go-test fmt fmtcheck verify-vendor verify create-release-files release
build-static:
build-static: ## Build garm statically
@echo Building garm
docker build --tag $(IMAGE_TAG) -f Dockerfile.build-static .
docker run --rm -e USER_ID=$(USER_ID) -e GARM_REF=$(GARM_REF) -e USER_GROUP=$(USER_GROUP) -v $(PWD)/build:/build/output:z $(IMAGE_TAG) /build-static.sh
$(IMAGE_BUILDER) build $(EXTRA_ARGS) --tag $(IMAGE_TAG) -f Dockerfile.build-static .
mkdir -p build
$(IMAGE_BUILDER) run --rm -e USER_ID=$(USER_ID) -e GARM_REF=$(GARM_REF) -e USER_GROUP=$(USER_GROUP) -v $(PWD)/build:/build/output:z $(IMAGE_TAG) /build-static.sh
@echo Binaries are available in $(PWD)/build
clean: ## Clean up build artifacts
@rm -rf ./bin ./build ./release
.PHONY: build
build: ## Build garm
@echo Building garm ${VERSION}
$(shell mkdir -p ./bin)
@$(GO) build -ldflags "-s -w -X github.com/cloudbase/garm/util/appdefaults.Version=${VERSION}" -tags osusergo,netgo,sqlite_omit_load_extension -o bin/garm ./cmd/garm
@$(GO) build -ldflags "-s -w -X github.com/cloudbase/garm/util/appdefaults.Version=${VERSION}" -tags osusergo,netgo,sqlite_omit_load_extension -o bin/garm-cli ./cmd/garm-cli
@echo Binaries are available in $(PWD)/bin
.PHONY: build-webui
build-webui:
@echo Building GARM web ui
./build-webapp.sh
rm -rf webapp/assets/_app
cp -r webapp/build/* webapp/assets/
.PHONY: generate
generate: ## Run go generate after checking required tools are in PATH
@echo Checking required tools...
@which openapi-generator-cli > /dev/null || (echo "Error: openapi-generator-cli not found in PATH" && exit 1)
@echo Running go generate
@$(GO) generate ./...
test: verify go-test ## Run tests
##@ Release
create-release-files:
./scripts/make-release.sh
release: build-static create-release-files
release: build-static create-release-files ## Create a release
clean:
@rm -rf ./bin ./build ./release
##@ Lint / Verify
.PHONY: lint
lint: golangci-lint $(GOLANGCI_LINT) ## Run linting.
$(GOLANGCI_LINT) run -v --build-tags=testing,integration $(GOLANGCI_LINT_EXTRA_ARGS)
build:
@echo Building garm ${VERSION}
$(shell mkdir -p ./bin)
@$(GO) build -ldflags "-s -w -X main.Version=${VERSION}" -tags osusergo,netgo,sqlite_omit_load_extension -o bin/garm ./cmd/garm
@$(GO) build -ldflags "-s -w -X github.com/cloudbase/garm/cmd/garm-cli/cmd.Version=${VERSION}" -tags osusergo,netgo,sqlite_omit_load_extension -o bin/garm-cli ./cmd/garm-cli
@echo Binaries are available in $(PWD)/bin
test: verify go-test
install-lint-deps:
@$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
lint:
@golangci-lint run --timeout=8m --build-tags testing
go-test:
@$(GO) test -race -mod=vendor -tags testing -v $(TEST_ARGS) -timeout=15m -parallel=4 -count=1 ./...
fmt:
@$(GO) fmt $$(go list ./...)
fmtcheck:
@gofmt -l -s $$(go list ./... | sed 's|github.com/cloudbase/garm/||g') | grep ".*\.go"; if [ "$$?" -eq 0 ]; then echo "gofmt check failed; please run gofmt -w -s"; exit 1;fi
.PHONY: lint-fix
lint-fix: golangci-lint $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linte
GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint
verify-vendor: ## verify if all the go.mod/go.sum files are up-to-date
$(eval TMPDIR := $(shell mktemp -d))
@cp -R ${ROOTDIR} ${TMPDIR}
@cp -R ${ROOTDIR} ${TMPDIR}/.
@(cd ${TMPDIR}/garm && ${GO} mod tidy)
@diff -r -u -q ${ROOTDIR} ${TMPDIR}/garm >/dev/null 2>&1; if [ "$$?" -ne 0 ];then echo "please run: go mod tidy && go mod vendor"; exit 1; fi
@rm -rf ${TMPDIR}
verify: verify-vendor lint fmtcheck
verify: verify-vendor lint fmtcheck ## Run all verify-* targets
integration: build ## Run integration tests
function cleanup {
if [ -e "$$GITHUB_ENV" ];then
source $$GITHUB_ENV
fi
./test/integration/scripts/taredown_garm.sh
$(GO) run ./test/integration/gh_cleanup/main.go
}
trap cleanup EXIT
@./test/integration/scripts/setup-garm.sh
@$(GO) test -v ./test/integration/. -timeout=30m -tags=integration
##@ Development
go-test: ## Run tests
@$(GO) test -race -mod=vendor -tags testing -v $(TEST_ARGS) -timeout=15m -parallel=4 -count=1 ./...
fmt: ## Run go fmt against code.
@$(GO) fmt $$(go list ./...)
webui-test:
(cd webapp && npm install)
(cd webapp && npm run test:run)
##@ Build Dependencies
## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
mkdir -p $(LOCALBIN)
## Tool Binaries
GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint
## Tool Versions
GOLANGCI_LINT_VERSION ?= v1.64.8
.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. If wrong version is installed, it will be overwritten.
$(GOLANGCI_LINT): $(LOCALBIN)
test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint --version | grep -q $(GOLANGCI_LINT_VERSION) || \
GOBIN=$(LOCALBIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)

109
README.md
View file

@ -1,16 +1,59 @@
<p align="center">
<img src="doc/images/garm-light.svg#gh-light-mode-only" width="384px" alt="Light mode image" />
<img src="doc/images/garm-dark.svg#gh-dark-mode-only" width="384px" alt="Dark mode image" />
</p>
# GitHub Actions Runner Manager (GARM)
[![Go Tests](https://github.com/cloudbase/garm/actions/workflows/go-tests.yml/badge.svg)](https://github.com/cloudbase/garm/actions/workflows/go-tests.yml)
<!-- TOC -->
- [GitHub Actions Runner Manager GARM](#github-actions-runner-manager-garm)
- [About GARM](#about-garm)
- [Join us on slack](#join-us-on-slack)
- [Installing](#installing)
- [Quickstart](#quickstart)
- [Installing on Kubernetes](#installing-on-kubernetes)
- [Configuring GARM for GHES](#configuring-garm-for-ghes)
- [Configuring GARM for Gitea](#configuring-garm-for-gitea)
- [Enabling the web UI](#enabling-the-web-ui)
- [Using GARM](#using-garm)
- [Supported providers](#supported-providers)
- [Installing external providers](#installing-external-providers)
- [Optimizing your runners](#optimizing-your-runners)
- [Write your own provider](#write-your-own-provider)
<!-- /TOC -->
## About GARM
Welcome to GARM!
GARM enables you to create and automatically maintain pools of [self-hosted GitHub runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners), with auto-scaling that can be used inside your github workflow runs.
GARM enables you to create and automatically maintain pools of self-hosted runners in both [Github](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) and [Gitea](https://github.com/go-gitea/gitea/) with auto-scaling that can be used inside your workflow runs.
The goal of ```GARM``` is to be simple to set up, simple to configure and simple to use. It is a single binary that can run on any GNU/Linux machine without any other requirements other than the providers it creates the runners in. It is intended to be easy to deploy in any environment and can create runners in any system you can write a provider for. There is no complicated setup process and no extremely complex concepts to understand. Once set up, it's meant to stay out of your way.
The goal of ```GARM``` is to be simple to set up, simple to configure and simple to use. The server itself is a single binary that can run on any GNU/Linux machine without any other requirements other than the providers you want to enable in your setup. It is intended to be easy to deploy in any environment and can create runners in virtually any system you can write a provider for (if one does not alreay exist). There is no complicated setup process and no extremely complex concepts to understand. Once set up, it's meant to stay out of your way.
GARM supports creating pools on either GitHub itself or on your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.5/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.
Through the use of providers, `GARM` can create runners in a variety of environments using the same `GARM` instance. Whether you want to create runners in your OpenStack cloud, your Azure cloud or your Kubernetes cluster, that is easily achieved by installing the appropriate providers, configuring them in `GARM` and creating pools that use them. You can create zero-runner pools for instances with high costs (large VMs, GPU enabled instances, etc) and have them spin up on demand, or you can create large pools of eagerly created k8s backed runners that can be used for your CI/CD pipelines at a moment's notice. You can mix them up and create pools in any combination of providers or resource allocations you want.
Through the use of providers, `GARM` can create runners in a variety of environments using the same `GARM` instance. Want to create pools of runners in your OpenStack cloud, your Azure cloud and your Kubernetes cluster? No problem! Just install the appropriate providers, configure them in `GARM` and you're good to go. Create zero-runner pools for instances with high costs (large VMs, GPU enabled instances, etc) and have them spin up on demand, or create large pools of k8s backed runners that can be used for your CI/CD pipelines at a moment's notice. You can mix them up and create pools in any combination of providers or resource allocations you want.
GARM supports two modes of operation:
* Pools
* Scale sets
Here is a brief architectural diagram of how pools work and how GARM reacts to workflows triggered in GitHub (click the image to see a larger version):
![GARM architecture diagram](/doc/images/garm-light.diagram.svg?raw=true#gh-light-mode-only)
![GARM architecture diagram](/doc/images/garm-dark.diagram.svg?raw=true#gh-dark-mode-only)
**Scale sets** work differently. While pools (as they are defined in GARM) rely on webhooks to know when a job was started and GARM needs to internally make the right decission in terms of which pool should handle that runner, scale sets have a lot of the scheduling and decission making logic done in GitHub itself.
> [!IMPORTANT]
> The README and documentation in the `main` branch are relevant to the not yet released code that is present in `main`. Following the documentation from the `main` branch for a stable release of GARM, may lead to errors. To view the documentation for the latest stable release, please switch to the appropriate tag. For information about setting up `v0.1.6`, please refer to the [v0.1.6 tag](https://github.com/cloudbase/garm/tree/v0.1.6).
> [!CAUTION]
> The `main` branch holds the latest code and is not guaranteed to be stable. If you are looking for a stable release, please check the releases page. If you plan to use the `main` branch, please do so on a new instance. Do not upgrade from a stable release to `main`.
## Join us on slack
@ -20,42 +63,64 @@ Whether you're running into issues or just want to drop by and say "hi", feel fr
## Installing
### On virtual or physical machines
### Quickstart
Check out the [quickstart](/doc/quickstart.md) document for instructions on how to install ```GARM```. If you'd like to build from source, check out the [building from source](/doc/building_from_source.md) document.
### On Kubernetes
### Installing on Kubernetes
Thanks to the efforts of the amazing folks at @mercedes-benz, GARM can now be integrated into k8s via their operator. Check out the [GARM operator](https://github.com/mercedes-benz/garm-operator/) for more details.
Thanks to the efforts of the amazing folks at [@mercedes-benz](https://github.com/mercedes-benz/), GARM can now be integrated into k8s via their operator. Check out the [GARM operator](https://github.com/mercedes-benz/garm-operator/) for more details.
## Configuring GARM for GHES
GARM supports creating pools and scale sets in either GitHub itself or in your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.10/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.
## Configuring GARM for Gitea
GARM now has support for Gitea (>=1.24.0). For information on getting started with Gitea, see the [Gitea quickstart](/doc/gitea.md) document.
## Enabling the web UI
GARM now ships with a single page application. To enable it, add the following to your GARM config:
```toml
[apiserver.webui]
enable = true
```
Check the [README.md](/webapp/README.md) file for details on the web UI.
## Using GARM
GARM is designed with simplicity in mind. At least we try to keep it as simple as possible. We're aware that adding a new tool in your workflow can be painful, especially when you already have to deal with so many. The cognitive load for OPS has reached a level where it feels overwhelming at times to even wrap your head around a new tool. As such, we believe that tools should be simple, should take no more than a few hours to understand and set up and if you absolutely need to interact with the tool, it should be as intuitive as possible. Although we try our best to make this happen, we're aware that GARM has some rough edges, especially for new users. If you encounter issues or feel like the setup process was too complicated, please let us know. We're always looking to improve the user experience.
We've written a short introduction into some of the commands that GARM has and some of the concepts involved in setting up GARM, managing runners and how GitHub does some of the things it does.
[You can find it here](/doc/using_garm.md).
Please, feel free to [open an issue](https://github.com/cloudbase/garm/issues/new) if you find the documentation lacking and would like more info. Sometimes we forget the challenges that new users face as we're so close to the code and how it works. Any feedback is welcome and we're always looking to improve the documentation.
## Supported providers
GARM uses providers to create runners in a particular IaaS. The providers are external executables that GARM calls into to create runners. Before you can create runners, you'll need to install at least one provider.
## Installing external providers
### Installing external providers
External providers are binaries that GARM calls into to create runners in a particular IaaS. There are several external providers available:
* [OpenStack](https://github.com/cloudbase/garm-provider-openstack)
* [Akamai/Linode](https://github.com/flatcar/garm-provider-linode) - Experimental
* [Amazon EC2](https://github.com/cloudbase/garm-provider-aws)
* [Azure](https://github.com/cloudbase/garm-provider-azure)
* [Equinix Metal](https://github.com/cloudbase/garm-provider-equinix)
* [Google Cloud Platform (GCP)](https://github.com/cloudbase/garm-provider-gcp)
* [Incus](https://github.com/cloudbase/garm-provider-incus)
* [Kubernetes](https://github.com/mercedes-benz/garm-provider-k8s) - Thanks to the amazing folks at @mercedes-benz for sharing their awesome provider!
* [LXD](https://github.com/cloudbase/garm-provider-lxd)
* [Incus](https://github.com/cloudbase/garm-provider-incus)
* [OpenStack](https://github.com/cloudbase/garm-provider-openstack)
* [Oracle Cloud Infrastructure (OCI)](https://github.com/cloudbase/garm-provider-oci)
Follow the instructions in the README of each provider to install them.
## Configuration
The ```GARM``` configuration is a simple ```toml```. The sample config file in [the testdata folder](/testdata/config.toml) is fairly well commented and should be enough to get you started. The configuration file is split into several sections, each of which is documented in its own page. The sections are:
* [The default section](/doc/config_default.md)
* [Database](/doc/database.md)
* [Github credentials](/doc/github_credentials.md)
* [Providers](/doc/providers.md)
* [Metrics](/doc/config_metrics.md)
* [JWT authentication](/doc/config_jwt_auth.md)
* [API server](/doc/config_api_server.md)
## Optimizing your runners
If you would like to optimize the startup time of new instance, take a look at the [performance considerations](/doc/performance_considerations.md) page.

View file

@ -15,30 +15,59 @@
package controllers
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"log/slog"
"net/http"
"net/url"
"strings"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm-provider-common/util"
"github.com/cloudbase/garm/apiserver/params"
"github.com/cloudbase/garm/auth"
"github.com/cloudbase/garm/config"
"github.com/cloudbase/garm/metrics"
runnerParams "github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner"
"github.com/cloudbase/garm/runner" //nolint:typecheck
garmUtil "github.com/cloudbase/garm/util"
wsWriter "github.com/cloudbase/garm/websocket"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/cloudbase/garm/workers/websocket/events"
)
func NewAPIController(r *runner.Runner, authenticator *auth.Authenticator, hub *wsWriter.Hub) (*APIController, error) {
controllerInfo, err := r.GetControllerInfo(auth.GetAdminContext())
func NewAPIController(r *runner.Runner, authenticator *auth.Authenticator, hub *wsWriter.Hub, apiCfg config.APIServer) (*APIController, error) {
controllerInfo, err := r.GetControllerInfo(auth.GetAdminContext(context.Background()))
if err != nil {
return nil, errors.Wrap(err, "failed to get controller info")
return nil, fmt.Errorf("failed to get controller info: %w", err)
}
var checkOrigin func(r *http.Request) bool
if len(apiCfg.CORSOrigins) > 0 {
checkOrigin = func(r *http.Request) bool {
origin := r.Header["Origin"]
if len(origin) == 0 {
return true
}
u, err := url.Parse(origin[0])
if err != nil {
return false
}
for _, val := range apiCfg.CORSOrigins {
corsVal, err := url.Parse(val)
if err != nil {
continue
}
if garmUtil.ASCIIEqualFold(u.Host, corsVal.Host) {
return true
}
}
return false
}
}
return &APIController{
r: r,
@ -47,6 +76,7 @@ func NewAPIController(r *runner.Runner, authenticator *auth.Authenticator, hub *
upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 16384,
CheckOrigin: checkOrigin,
},
controllerID: controllerInfo.ControllerID.String(),
}, nil
@ -60,26 +90,24 @@ type APIController struct {
controllerID string
}
func handleError(w http.ResponseWriter, err error) {
func handleError(ctx context.Context, w http.ResponseWriter, err error) {
w.Header().Set("Content-Type", "application/json")
origErr := errors.Cause(err)
apiErr := params.APIErrorResponse{
Details: origErr.Error(),
Details: err.Error(),
}
switch origErr.(type) {
case *gErrors.NotFoundError:
switch {
case errors.Is(err, gErrors.ErrNotFound):
w.WriteHeader(http.StatusNotFound)
apiErr.Error = "Not Found"
case *gErrors.UnauthorizedError:
case errors.Is(err, gErrors.ErrUnauthorized):
w.WriteHeader(http.StatusUnauthorized)
apiErr.Error = "Not Authorized"
// Don't include details on 401 errors.
apiErr.Details = ""
case *gErrors.BadRequestError:
case errors.Is(err, gErrors.ErrBadRequest):
w.WriteHeader(http.StatusBadRequest)
apiErr.Error = "Bad Request"
case *gErrors.DuplicateUserError, *gErrors.ConflictError:
case errors.Is(err, gErrors.ErrDuplicateEntity), errors.Is(err, &gErrors.ConflictError{}):
w.WriteHeader(http.StatusConflict)
apiErr.Error = "Conflict"
default:
@ -90,62 +118,62 @@ func handleError(w http.ResponseWriter, err error) {
}
if err := json.NewEncoder(w).Encode(apiErr); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
func (a *APIController) webhookMetricLabelValues(valid, reason string) []string {
controllerInfo, err := a.r.GetControllerInfo(auth.GetAdminContext())
if err != nil {
log.Printf("failed to get controller info: %s", err)
// If labels are empty, not attempt will be made to record webhook.
return []string{}
}
return []string{
valid, reason,
controllerInfo.Hostname, controllerInfo.ControllerID.String(),
}
}
func (a *APIController) handleWorkflowJobEvent(w http.ResponseWriter, r *http.Request) {
func (a *APIController) handleWorkflowJobEvent(ctx context.Context, w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
if err != nil {
handleError(w, gErrors.NewBadRequestError("invalid post body: %s", err))
handleError(ctx, w, gErrors.NewBadRequestError("invalid post body: %s", err))
return
}
signature := r.Header.Get("X-Hub-Signature-256")
hookType := r.Header.Get("X-Github-Hook-Installation-Target-Type")
giteaTargetType := r.Header.Get("X-Gitea-Hook-Installation-Target-Type")
var labelValues []string
defer func() {
if len(labelValues) == 0 {
forgeType := runnerParams.GithubEndpointType
if giteaTargetType != "" {
forgeType = runnerParams.GiteaEndpointType
hookType = giteaTargetType
}
if err := a.r.DispatchWorkflowJob(hookType, signature, forgeType, body); err != nil {
switch {
case errors.Is(err, gErrors.ErrNotFound):
metrics.WebhooksReceived.WithLabelValues(
"false", // label: valid
"owner_unknown", // label: reason
).Inc()
slog.With(slog.Any("error", err)).ErrorContext(ctx, "got not found error from DispatchWorkflowJob. webhook not meant for us?")
return
}
if err := metrics.RecordWebhookWithLabels(labelValues...); err != nil {
log.Printf("failed to record metric: %s", err)
}
}()
if err := a.r.DispatchWorkflowJob(hookType, signature, body); err != nil {
if errors.Is(err, gErrors.ErrNotFound) {
labelValues = a.webhookMetricLabelValues("false", "owner_unknown")
log.Printf("got not found error from DispatchWorkflowJob. webhook not meant for us?: %q", err)
return
} else if strings.Contains(err.Error(), "signature") { // TODO: check error type
labelValues = a.webhookMetricLabelValues("false", "signature_invalid")
} else {
labelValues = a.webhookMetricLabelValues("false", "unknown")
case strings.Contains(err.Error(), "signature"):
// nolint:golangci-lint,godox TODO: check error type
metrics.WebhooksReceived.WithLabelValues(
"false", // label: valid
"signature_invalid", // label: reason
).Inc()
default:
metrics.WebhooksReceived.WithLabelValues(
"false", // label: valid
"unknown", // label: reason
).Inc()
}
handleError(w, err)
handleError(ctx, w, err)
return
}
labelValues = a.webhookMetricLabelValues("true", "")
metrics.WebhooksReceived.WithLabelValues(
"true", // label: valid
"", // label: reason
).Inc()
}
func (a *APIController) WebhookHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
controllerID, ok := vars["controllerID"]
// If the webhook URL includes a controller ID, we validate that it's meant for us. We still
@ -154,7 +182,7 @@ func (a *APIController) WebhookHandler(w http.ResponseWriter, r *http.Request) {
// via garm. We cannot tag a webhook URL on github, so there is no way to determine ownership.
// Using a controllerID suffix is a simple way to denote ownership.
if ok && controllerID != a.controllerID {
log.Printf("ignoring webhook meant for controller %s", util.SanitizeLogEntry(controllerID))
slog.InfoContext(ctx, "ignoring webhook meant for foreign controller", "req_controller_id", controllerID)
return
}
@ -163,11 +191,49 @@ func (a *APIController) WebhookHandler(w http.ResponseWriter, r *http.Request) {
event := runnerParams.Event(headers.Get("X-Github-Event"))
switch event {
case runnerParams.WorkflowJobEvent:
a.handleWorkflowJobEvent(w, r)
a.handleWorkflowJobEvent(ctx, w, r)
case runnerParams.PingEvent:
// Ignore ping event. We may want to save the ping in the github entity table in the future.
default:
log.Printf("ignoring unknown event %s", util.SanitizeLogEntry(string(event)))
slog.DebugContext(ctx, "ignoring unknown event", "gh_event", util.SanitizeLogEntry(string(event)))
}
}
func (a *APIController) EventsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if !auth.IsAdmin(ctx) {
w.WriteHeader(http.StatusForbidden)
if _, err := w.Write([]byte("events are available to admin users")); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
conn, err := a.upgrader.Upgrade(w, r, nil)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error upgrading to websockets")
return
}
defer conn.Close()
wsClient, err := wsWriter.NewClient(ctx, conn)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create new client")
return
}
defer wsClient.Stop()
eventHandler, err := events.NewHandler(ctx, wsClient)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create new event handler")
return
}
if err := eventHandler.Start(); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to start event handler")
return
}
<-eventHandler.Done()
}
func (a *APIController) WSHandler(writer http.ResponseWriter, req *http.Request) {
@ -175,41 +241,45 @@ func (a *APIController) WSHandler(writer http.ResponseWriter, req *http.Request)
if !auth.IsAdmin(ctx) {
writer.WriteHeader(http.StatusForbidden)
if _, err := writer.Write([]byte("you need admin level access to view logs")); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if a.hub == nil {
handleError(writer, gErrors.NewBadRequestError("log streamer is disabled"))
handleError(ctx, writer, gErrors.NewBadRequestError("log streamer is disabled"))
return
}
conn, err := a.upgrader.Upgrade(writer, req, nil)
if err != nil {
log.Printf("error upgrading to websockets: %v", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error upgrading to websockets")
return
}
defer conn.Close()
// TODO (gsamfira): Handle ExpiresAt. Right now, if a client uses
// a valid token to authenticate, and keeps the websocket connection
// open, it will allow that client to stream logs via websockets
// until the connection is broken. We need to forcefully disconnect
// the client once the token expires.
client, err := wsWriter.NewClient(conn, a.hub)
client, err := wsWriter.NewClient(ctx, conn)
if err != nil {
log.Printf("failed to create new client: %v", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create new client")
return
}
if err := a.hub.Register(client); err != nil {
log.Printf("failed to register new client: %v", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to register new client")
return
}
client.Go()
defer a.hub.Unregister(client)
if err := client.Start(); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to start client")
return
}
<-client.Done()
slog.Info("client disconnected", "client_id", client.ID())
}
// NotFoundHandler is returned when an invalid URL is acccessed
func (a *APIController) NotFoundHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
apiErr := params.APIErrorResponse{
Details: "Resource not found",
Error: "Not found",
@ -218,7 +288,7 @@ func (a *APIController) NotFoundHandler(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusNotFound)
if err := json.NewEncoder(w).Encode(apiErr); err != nil {
log.Printf("failet to write response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failet to write response")
}
}
@ -233,19 +303,19 @@ func (a *APIController) MetricsTokenHandler(w http.ResponseWriter, r *http.Reque
ctx := r.Context()
if !auth.IsAdmin(ctx) {
handleError(w, gErrors.ErrUnauthorized)
handleError(ctx, w, gErrors.ErrUnauthorized)
return
}
token, err := a.auth.GetJWTMetricsToken(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(runnerParams.JWTResponse{Token: token})
if err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -266,32 +336,32 @@ func (a *APIController) MetricsTokenHandler(w http.ResponseWriter, r *http.Reque
//
// LoginHandler returns a jwt token
func (a *APIController) LoginHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var loginInfo runnerParams.PasswordLoginParams
if err := json.NewDecoder(r.Body).Decode(&loginInfo); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := loginInfo.Validate(); err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
ctx := r.Context()
ctx, err := a.auth.AuthenticateUser(ctx, loginInfo)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
tokenString, err := a.auth.GetJWTToken(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(runnerParams.JWTResponse{Token: tokenString}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -310,49 +380,27 @@ func (a *APIController) LoginHandler(w http.ResponseWriter, r *http.Request) {
// 200: User
// 400: APIErrorResponse
func (a *APIController) FirstRunHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if a.auth.IsInitialized() {
err := gErrors.NewConflictError("already initialized")
handleError(w, err)
handleError(ctx, w, err)
return
}
ctx := r.Context()
var newUserParams runnerParams.NewUserParams
if err := json.NewDecoder(r.Body).Decode(&newUserParams); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
newUser, err := a.auth.InitController(ctx, newUserParams)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(newUser); err != nil {
log.Printf("failed to encode response: %q", err)
}
}
// swagger:route GET /credentials credentials ListCredentials
//
// List all credentials.
//
// Responses:
// 200: Credentials
// 400: APIErrorResponse
func (a *APIController) ListCredentials(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
creds, err := a.r.ListCredentials(ctx)
if err != nil {
handleError(w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(creds); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -367,13 +415,13 @@ func (a *APIController) ListProviders(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
providers, err := a.r.ListProviders(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(providers); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -388,13 +436,13 @@ func (a *APIController) ListAllJobs(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
jobs, err := a.r.ListAllJobs(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(jobs); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -409,12 +457,51 @@ func (a *APIController) ControllerInfoHandler(w http.ResponseWriter, r *http.Req
ctx := r.Context()
info, err := a.r.GetControllerInfo(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route PUT /controller controller UpdateController
//
// Update controller.
//
// Parameters:
// + name: Body
// description: Parameters used when updating the controller.
// type: UpdateControllerParams
// in: body
// required: true
//
// Responses:
// 200: ControllerInfo
// 400: APIErrorResponse
func (a *APIController) UpdateControllerHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var updateParams runnerParams.UpdateControllerParams
if err := json.NewDecoder(r.Body).Decode(&updateParams); err != nil {
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := updateParams.Validate(); err != nil {
handleError(ctx, w, err)
return
}
info, err := a.r.UpdateController(ctx, updateParams)
if err != nil {
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -16,14 +16,14 @@ package controllers
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
"github.com/gorilla/mux"
)
// swagger:route POST /enterprises enterprises CreateEnterprise
@ -45,20 +45,20 @@ func (a *APIController) CreateEnterpriseHandler(w http.ResponseWriter, r *http.R
var enterpriseData runnerParams.CreateEnterpriseParams
if err := json.NewDecoder(r.Body).Decode(&enterpriseData); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
enterprise, err := a.r.CreateEnterprise(ctx, enterpriseData)
if err != nil {
log.Printf("error creating enterprise: %+v", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating enterprise")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(enterprise); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -66,22 +66,39 @@ func (a *APIController) CreateEnterpriseHandler(w http.ResponseWriter, r *http.R
//
// List all enterprises.
//
// Parameters:
// + name: name
// description: Exact enterprise name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses:
// 200: Enterprises
// default: APIErrorResponse
func (a *APIController) ListEnterprisesHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
enterprise, err := a.r.ListEnterprises(ctx)
filter := runnerParams.EnterpriseFilter{
Name: r.URL.Query().Get("name"),
Endpoint: r.URL.Query().Get("endpoint"),
}
enterprise, err := a.r.ListEnterprises(ctx, filter)
if err != nil {
log.Printf("listing enterprise: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing enterprise")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(enterprise); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -110,21 +127,21 @@ func (a *APIController) GetEnterpriseByIDHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
enterprise, err := a.r.GetEnterpriseByID(ctx, enterpriseID)
if err != nil {
log.Printf("fetching enterprise: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching enterprise")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(enterprise); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -152,20 +169,19 @@ func (a *APIController) DeleteEnterpriseHandler(w http.ResponseWriter, r *http.R
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.DeleteEnterprise(ctx, enterpriseID); err != nil {
log.Printf("removing enterprise: %+v", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing enterprise")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /enterprises/{enterpriseID} enterprises UpdateEnterprise
@ -198,27 +214,27 @@ func (a *APIController) UpdateEnterpriseHandler(w http.ResponseWriter, r *http.R
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var updatePayload runnerParams.UpdateEntityParams
if err := json.NewDecoder(r.Body).Decode(&updatePayload); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
enterprise, err := a.r.UpdateEnterprise(ctx, enterpriseID, updatePayload)
if err != nil {
log.Printf("error updating enterprise: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error updating enterprise: %s")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(enterprise); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -253,28 +269,84 @@ func (a *APIController) CreateEnterprisePoolHandler(w http.ResponseWriter, r *ht
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.CreatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.CreateEnterprisePool(ctx, enterpriseID, poolData)
if err != nil {
log.Printf("error creating enterprise pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating enterprise pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route POST /enterprises/{enterpriseID}/scalesets enterprises scalesets CreateEnterpriseScaleSet
//
// Create enterprise pool with the parameters given.
//
// Parameters:
// + name: enterpriseID
// description: Enterprise ID.
// type: string
// in: path
// required: true
//
// + name: Body
// description: Parameters used when creating the enterprise scale set.
// type: CreateScaleSetParams
// in: body
// required: true
//
// Responses:
// 200: ScaleSet
// default: APIErrorResponse
func (a *APIController) CreateEnterpriseScaleSetHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
enterpriseID, ok := vars["enterpriseID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var scaleSetData runnerParams.CreateScaleSetParams
if err := json.NewDecoder(r.Body).Decode(&scaleSetData); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
scaleSet, err := a.r.CreateEntityScaleSet(ctx, runnerParams.ForgeEntityTypeEnterprise, enterpriseID, scaleSetData)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating enterprise scale set")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSet); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -302,23 +374,64 @@ func (a *APIController) ListEnterprisePoolsHandler(w http.ResponseWriter, r *htt
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pools, err := a.r.ListEnterprisePools(ctx, enterpriseID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pools); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /enterprises/{enterpriseID}/scalesets enterprises scalesets ListEnterpriseScaleSets
//
// List enterprise scale sets.
//
// Parameters:
// + name: enterpriseID
// description: Enterprise ID.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ScaleSets
// default: APIErrorResponse
func (a *APIController) ListEnterpriseScaleSetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
enterpriseID, ok := vars["enterpriseID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
scaleSets, err := a.r.ListEntityScaleSets(ctx, runnerParams.ForgeEntityTypeEnterprise, enterpriseID)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing scale sets")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSets); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /enterprises/{enterpriseID}/pools/{poolID} enterprises pools GetEnterprisePool
@ -352,21 +465,21 @@ func (a *APIController) GetEnterprisePoolHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No enterprise or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pool, err := a.r.GetEnterprisePoolByID(ctx, enterpriseID, poolID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -401,20 +514,19 @@ func (a *APIController) DeleteEnterprisePoolHandler(w http.ResponseWriter, r *ht
Error: "Bad Request",
Details: "No enterprise or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.DeleteEnterprisePool(ctx, enterpriseID, poolID); err != nil {
log.Printf("removing pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /enterprises/{enterpriseID}/pools/{poolID} enterprises pools UpdateEnterprisePool
@ -455,27 +567,27 @@ func (a *APIController) UpdateEnterprisePoolHandler(w http.ResponseWriter, r *ht
Error: "Bad Request",
Details: "No enterprise or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.UpdatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.UpdateEnterprisePool(ctx, enterpriseID, poolID, poolData)
if err != nil {
log.Printf("error creating enterprise pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating enterprise pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -0,0 +1,241 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package controllers
import (
"encoding/json"
"log/slog"
"math"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
)
// swagger:route GET /gitea/credentials credentials ListGiteaCredentials
//
// List all credentials.
//
// Responses:
// 200: Credentials
// 400: APIErrorResponse
func (a *APIController) ListGiteaCredentials(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
creds, err := a.r.ListGiteaCredentials(ctx)
if err != nil {
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(creds); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route POST /gitea/credentials credentials CreateGiteaCredentials
//
// Create a Gitea credential.
//
// Parameters:
// + name: Body
// description: Parameters used when creating a Gitea credential.
// type: CreateGiteaCredentialsParams
// in: body
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) CreateGiteaCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var params params.CreateGiteaCredentialsParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.CreateGiteaCredentials(ctx, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create Gitea credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /gitea/credentials/{id} credentials GetGiteaCredentials
//
// Get a Gitea credential.
//
// Parameters:
// + name: id
// description: ID of the Gitea credential.
// type: integer
// in: path
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) GetGiteaCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.GetGiteaCredentials(ctx, uint(id))
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to get Gitea credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route DELETE /gitea/credentials/{id} credentials DeleteGiteaCredentials
//
// Delete a Gitea credential.
//
// Parameters:
// + name: id
// description: ID of the Gitea credential.
// type: integer
// in: path
// required: true
//
// Responses:
// default: APIErrorResponse
func (a *APIController) DeleteGiteaCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.DeleteGiteaCredentials(ctx, uint(id)); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete Gitea credential")
handleError(ctx, w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// swagger:route PUT /gitea/credentials/{id} credentials UpdateGiteaCredentials
//
// Update a Gitea credential.
//
// Parameters:
// + name: id
// description: ID of the Gitea credential.
// type: integer
// in: path
// required: true
// + name: Body
// description: Parameters used when updating a Gitea credential.
// type: UpdateGiteaCredentialsParams
// in: body
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) UpdateGiteaCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
var params params.UpdateGiteaCredentialsParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.UpdateGiteaCredentials(ctx, uint(id), params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to update Gitea credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -0,0 +1,199 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package controllers
import (
"encoding/json"
"log/slog"
"net/http"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
)
// swagger:route POST /gitea/endpoints endpoints CreateGiteaEndpoint
//
// Create a Gitea Endpoint.
//
// Parameters:
// + name: Body
// description: Parameters used when creating a Gitea endpoint.
// type: CreateGiteaEndpointParams
// in: body
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) CreateGiteaEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var params params.CreateGiteaEndpointParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.CreateGiteaEndpoint(ctx, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create Gitea endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /gitea/endpoints endpoints ListGiteaEndpoints
//
// List all Gitea Endpoints.
//
// Responses:
// 200: ForgeEndpoints
// default: APIErrorResponse
func (a *APIController) ListGiteaEndpoints(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
endpoints, err := a.r.ListGiteaEndpoints(ctx)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to list Gitea endpoints")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoints); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /gitea/endpoints/{name} endpoints GetGiteaEndpoint
//
// Get a Gitea Endpoint.
//
// Parameters:
// + name: name
// description: The name of the Gitea endpoint.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) GetGiteaEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.GetGiteaEndpoint(ctx, name)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to get Gitea endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route DELETE /gitea/endpoints/{name} endpoints DeleteGiteaEndpoint
//
// Delete a Gitea Endpoint.
//
// Parameters:
// + name: name
// description: The name of the Gitea endpoint.
// type: string
// in: path
// required: true
//
// Responses:
// default: APIErrorResponse
func (a *APIController) DeleteGiteaEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.DeleteGiteaEndpoint(ctx, name); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete Gitea endpoint")
handleError(ctx, w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// swagger:route PUT /gitea/endpoints/{name} endpoints UpdateGiteaEndpoint
//
// Update a Gitea Endpoint.
//
// Parameters:
// + name: name
// description: The name of the Gitea endpoint.
// type: string
// in: path
// required: true
// + name: Body
// description: Parameters used when updating a Gitea endpoint.
// type: UpdateGiteaEndpointParams
// in: body
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) UpdateGiteaEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
var params params.UpdateGiteaEndpointParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.UpdateGiteaEndpoint(ctx, name, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to update GitHub endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -0,0 +1,242 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package controllers
import (
"encoding/json"
"log/slog"
"math"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
)
// swagger:route GET /credentials credentials ListCredentials
// swagger:route GET /github/credentials credentials ListCredentials
//
// List all credentials.
//
// Responses:
// 200: Credentials
// 400: APIErrorResponse
func (a *APIController) ListCredentials(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
creds, err := a.r.ListCredentials(ctx)
if err != nil {
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(creds); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route POST /github/credentials credentials CreateCredentials
//
// Create a GitHub credential.
//
// Parameters:
// + name: Body
// description: Parameters used when creating a GitHub credential.
// type: CreateGithubCredentialsParams
// in: body
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) CreateGithubCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var params params.CreateGithubCredentialsParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.CreateGithubCredentials(ctx, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create GitHub credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /github/credentials/{id} credentials GetCredentials
//
// Get a GitHub credential.
//
// Parameters:
// + name: id
// description: ID of the GitHub credential.
// type: integer
// in: path
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) GetGithubCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.GetGithubCredentials(ctx, uint(id))
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to get GitHub credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route DELETE /github/credentials/{id} credentials DeleteCredentials
//
// Delete a GitHub credential.
//
// Parameters:
// + name: id
// description: ID of the GitHub credential.
// type: integer
// in: path
// required: true
//
// Responses:
// default: APIErrorResponse
func (a *APIController) DeleteGithubCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.DeleteGithubCredentials(ctx, uint(id)); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete GitHub credential")
handleError(ctx, w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// swagger:route PUT /github/credentials/{id} credentials UpdateCredentials
//
// Update a GitHub credential.
//
// Parameters:
// + name: id
// description: ID of the GitHub credential.
// type: integer
// in: path
// required: true
// + name: Body
// description: Parameters used when updating a GitHub credential.
// type: UpdateGithubCredentialsParams
// in: body
// required: true
//
// Responses:
// 200: ForgeCredentials
// 400: APIErrorResponse
func (a *APIController) UpdateGithubCredential(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
idParam, ok := vars["id"]
if !ok {
slog.ErrorContext(ctx, "missing id in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
id, err := strconv.ParseUint(idParam, 10, 64)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if id > math.MaxUint {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "id is too large")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
var params params.UpdateGithubCredentialsParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
cred, err := a.r.UpdateGithubCredentials(ctx, uint(id), params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to update GitHub credential")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(cred); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -0,0 +1,199 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package controllers
import (
"encoding/json"
"log/slog"
"net/http"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
)
// swagger:route POST /github/endpoints endpoints CreateGithubEndpoint
//
// Create a GitHub Endpoint.
//
// Parameters:
// + name: Body
// description: Parameters used when creating a GitHub endpoint.
// type: CreateGithubEndpointParams
// in: body
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) CreateGithubEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var params params.CreateGithubEndpointParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.CreateGithubEndpoint(ctx, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to create GitHub endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /github/endpoints endpoints ListGithubEndpoints
//
// List all GitHub Endpoints.
//
// Responses:
// 200: ForgeEndpoints
// default: APIErrorResponse
func (a *APIController) ListGithubEndpoints(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
endpoints, err := a.r.ListGithubEndpoints(ctx)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to list GitHub endpoints")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoints); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /github/endpoints/{name} endpoints GetGithubEndpoint
//
// Get a GitHub Endpoint.
//
// Parameters:
// + name: name
// description: The name of the GitHub endpoint.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) GetGithubEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.GetGithubEndpoint(ctx, name)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to get GitHub endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route DELETE /github/endpoints/{name} endpoints DeleteGithubEndpoint
//
// Delete a GitHub Endpoint.
//
// Parameters:
// + name: name
// description: The name of the GitHub endpoint.
// type: string
// in: path
// required: true
//
// Responses:
// default: APIErrorResponse
func (a *APIController) DeleteGithubEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.DeleteGithubEndpoint(ctx, name); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to delete GitHub endpoint")
handleError(ctx, w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// swagger:route PUT /github/endpoints/{name} endpoints UpdateGithubEndpoint
//
// Update a GitHub Endpoint.
//
// Parameters:
// + name: name
// description: The name of the GitHub endpoint.
// type: string
// in: path
// required: true
// + name: Body
// description: Parameters used when updating a GitHub endpoint.
// type: UpdateGithubEndpointParams
// in: body
// required: true
//
// Responses:
// 200: ForgeEndpoint
// default: APIErrorResponse
func (a *APIController) UpdateGithubEndpoint(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
name, ok := vars["name"]
if !ok {
slog.ErrorContext(ctx, "missing name in request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
var params params.UpdateGithubEndpointParams
if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode request")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
endpoint, err := a.r.UpdateGithubEndpoint(ctx, name, params)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to update GitHub endpoint")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(endpoint); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -16,15 +16,15 @@ package controllers
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
"github.com/gorilla/mux"
)
// swagger:route GET /pools/{poolID}/instances instances ListPoolInstances
@ -51,21 +51,69 @@ func (a *APIController) ListPoolInstancesHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
instances, err := a.r.ListPoolInstances(ctx, poolID)
if err != nil {
log.Printf("listing pool instances: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pool instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /scalesets/{scalesetID}/instances instances ListScaleSetInstances
//
// List runner instances in a scale set.
//
// Parameters:
// + name: scalesetID
// description: Runner scale set ID.
// type: string
// in: path
// required: true
//
// Responses:
// 200: Instances
// default: APIErrorResponse
func (a *APIController) ListScaleSetInstancesHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
scalesetID, ok := vars["scalesetID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No pool ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
id, err := strconv.ParseUint(scalesetID, 10, 32)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
instances, err := a.r.ListScaleSetInstances(ctx, uint(id))
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pool instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -93,21 +141,21 @@ func (a *APIController) GetInstanceHandler(w http.ResponseWriter, r *http.Reques
Error: "Bad Request",
Details: "No runner name specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
instance, err := a.r.GetInstance(ctx, instanceName)
if err != nil {
log.Printf("listing instances: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instance); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -128,8 +176,15 @@ func (a *APIController) GetInstanceHandler(w http.ResponseWriter, r *http.Reques
// in: query
// required: false
//
// Responses:
// default: APIErrorResponse
// + name: bypassGHUnauthorized
// description: If true GARM will ignore unauthorized errors returned by GitHub when removing a runner. This is useful if you want to clean up runners and your credentials have expired.
// type: boolean
// in: query
// required: false
//
// Responses:
//
// default: APIErrorResponse
func (a *APIController) DeleteInstanceHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
@ -140,15 +195,16 @@ func (a *APIController) DeleteInstanceHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No instance name specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
forceRemove, _ := strconv.ParseBool(r.URL.Query().Get("forceRemove"))
if err := a.r.DeleteRunner(ctx, instanceName, forceRemove); err != nil {
log.Printf("removing runner: %s", err)
handleError(w, err)
bypassGHUnauthorized, _ := strconv.ParseBool(r.URL.Query().Get("bypassGHUnauthorized"))
if err := a.r.DeleteRunner(ctx, instanceName, forceRemove, bypassGHUnauthorized); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing runner")
handleError(ctx, w, err)
return
}
@ -180,21 +236,21 @@ func (a *APIController) ListRepoInstancesHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
instances, err := a.r.ListRepoInstances(ctx, repoID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -222,21 +278,21 @@ func (a *APIController) ListOrgInstancesHandler(w http.ResponseWriter, r *http.R
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
instances, err := a.r.ListOrgInstances(ctx, orgID)
if err != nil {
log.Printf("listing instances: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -264,21 +320,21 @@ func (a *APIController) ListEnterpriseInstancesHandler(w http.ResponseWriter, r
Error: "Bad Request",
Details: "No enterprise ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
instances, err := a.r.ListEnterpriseInstances(ctx, enterpriseID)
if err != nil {
log.Printf("listing instances: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -294,14 +350,14 @@ func (a *APIController) ListAllInstancesHandler(w http.ResponseWriter, r *http.R
instances, err := a.r.ListAllInstances(ctx)
if err != nil {
log.Printf("listing instances: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing instances")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(instances); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -310,14 +366,34 @@ func (a *APIController) InstanceStatusMessageHandler(w http.ResponseWriter, r *h
var updateMessage runnerParams.InstanceUpdateMessage
if err := json.NewDecoder(r.Body).Decode(&updateMessage); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.AddInstanceStatusMessage(ctx, updateMessage); err != nil {
log.Printf("error saving status message: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error saving status message")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
func (a *APIController) InstanceSystemInfoHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var updateMessage runnerParams.UpdateSystemInfoParams
if err := json.NewDecoder(r.Body).Decode(&updateMessage); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.UpdateSystemInfo(ctx, updateMessage); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error saving status message")
handleError(ctx, w, err)
return
}

View file

@ -17,11 +17,12 @@ package controllers
import (
"encoding/json"
"fmt"
"log"
"log/slog"
"net/http"
"github.com/cloudbase/garm/apiserver/params"
"github.com/gorilla/mux"
"github.com/cloudbase/garm/apiserver/params"
)
func (a *APIController) InstanceGithubRegistrationTokenHandler(w http.ResponseWriter, r *http.Request) {
@ -29,14 +30,14 @@ func (a *APIController) InstanceGithubRegistrationTokenHandler(w http.ResponseWr
token, err := a.r.GetInstanceGithubRegistrationToken(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if _, err := w.Write([]byte(token)); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -50,7 +51,7 @@ func (a *APIController) JITCredentialsFileHandler(w http.ResponseWriter, r *http
Error: "Not Found",
Details: "Not Found",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
@ -59,8 +60,8 @@ func (a *APIController) JITCredentialsFileHandler(w http.ResponseWriter, r *http
data, err := a.r.GetJITConfigFile(ctx, dotFileName)
if err != nil {
log.Printf("getting JIT config file: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "getting JIT config file")
handleError(ctx, w, err)
return
}
@ -71,7 +72,7 @@ func (a *APIController) JITCredentialsFileHandler(w http.ResponseWriter, r *http
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
w.WriteHeader(http.StatusOK)
if _, err := w.Write(data); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -80,14 +81,14 @@ func (a *APIController) SystemdServiceNameHandler(w http.ResponseWriter, r *http
serviceName, err := a.r.GetRunnerServiceName(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
if _, err := w.Write([]byte(serviceName)); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -97,14 +98,14 @@ func (a *APIController) SystemdUnitFileHandler(w http.ResponseWriter, r *http.Re
data, err := a.r.GenerateSystemdUnitFile(ctx, runAsUser)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
if _, err := w.Write(data); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -113,12 +114,12 @@ func (a *APIController) RootCertificateBundleHandler(w http.ResponseWriter, r *h
bundle, err := a.r.GetRootCertificateBundle(ctx)
if err != nil {
handleError(w, err)
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(bundle); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -16,15 +16,15 @@ package controllers
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
"github.com/gorilla/mux"
)
// swagger:route POST /organizations organizations CreateOrg
@ -46,20 +46,20 @@ func (a *APIController) CreateOrgHandler(w http.ResponseWriter, r *http.Request)
var orgData runnerParams.CreateOrgParams
if err := json.NewDecoder(r.Body).Decode(&orgData); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
org, err := a.r.CreateOrganization(ctx, orgData)
if err != nil {
log.Printf("error creating organization: %+v", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating organization")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(org); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -67,22 +67,39 @@ func (a *APIController) CreateOrgHandler(w http.ResponseWriter, r *http.Request)
//
// List organizations.
//
// Parameters:
// + name: name
// description: Exact organization name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses:
// 200: Organizations
// default: APIErrorResponse
func (a *APIController) ListOrgsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
orgs, err := a.r.ListOrganizations(ctx)
filter := runnerParams.OrganizationFilter{
Name: r.URL.Query().Get("name"),
Endpoint: r.URL.Query().Get("endpoint"),
}
orgs, err := a.r.ListOrganizations(ctx, filter)
if err != nil {
log.Printf("listing orgs: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing orgs")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(orgs); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -111,21 +128,21 @@ func (a *APIController) GetOrgByIDHandler(w http.ResponseWriter, r *http.Request
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
org, err := a.r.GetOrganizationByID(ctx, orgID)
if err != nil {
log.Printf("fetching org: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching org")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(org); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -159,7 +176,7 @@ func (a *APIController) DeleteOrgHandler(w http.ResponseWriter, r *http.Request)
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
@ -167,14 +184,13 @@ func (a *APIController) DeleteOrgHandler(w http.ResponseWriter, r *http.Request)
keepWebhook, _ := strconv.ParseBool(r.URL.Query().Get("keepWebhook"))
if err := a.r.DeleteOrganization(ctx, orgID, keepWebhook); err != nil {
log.Printf("removing org: %+v", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing org")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /organizations/{orgID} organizations UpdateOrg
@ -208,27 +224,27 @@ func (a *APIController) UpdateOrgHandler(w http.ResponseWriter, r *http.Request)
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var updatePayload runnerParams.UpdateEntityParams
if err := json.NewDecoder(r.Body).Decode(&updatePayload); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
org, err := a.r.UpdateOrganization(ctx, orgID, updatePayload)
if err != nil {
log.Printf("error updating organization: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error updating organization")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(org); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -263,28 +279,84 @@ func (a *APIController) CreateOrgPoolHandler(w http.ResponseWriter, r *http.Requ
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.CreatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.CreateOrgPool(ctx, orgID, poolData)
if err != nil {
log.Printf("error creating organization pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating organization pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route POST /organizations/{orgID}/scalesets organizations scalesets CreateOrgScaleSet
//
// Create organization scale set with the parameters given.
//
// Parameters:
// + name: orgID
// description: Organization ID.
// type: string
// in: path
// required: true
//
// + name: Body
// description: Parameters used when creating the organization scale set.
// type: CreateScaleSetParams
// in: body
// required: true
//
// Responses:
// 200: ScaleSet
// default: APIErrorResponse
func (a *APIController) CreateOrgScaleSetHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
orgID, ok := vars["orgID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var scalesetData runnerParams.CreateScaleSetParams
if err := json.NewDecoder(r.Body).Decode(&scalesetData); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
scaleSet, err := a.r.CreateEntityScaleSet(ctx, runnerParams.ForgeEntityTypeOrganization, orgID, scalesetData)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating organization scale set")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSet); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -312,21 +384,63 @@ func (a *APIController) ListOrgPoolsHandler(w http.ResponseWriter, r *http.Reque
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pools, err := a.r.ListOrgPools(ctx, orgID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pools); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /organizations/{orgID}/scalesets organizations scalesets ListOrgScaleSets
//
// List organization scale sets.
//
// Parameters:
// + name: orgID
// description: Organization ID.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ScaleSets
// default: APIErrorResponse
func (a *APIController) ListOrgScaleSetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
orgID, ok := vars["orgID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
scaleSets, err := a.r.ListEntityScaleSets(ctx, runnerParams.ForgeEntityTypeOrganization, orgID)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing scale sets")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSets); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -361,21 +475,21 @@ func (a *APIController) GetOrgPoolHandler(w http.ResponseWriter, r *http.Request
Error: "Bad Request",
Details: "No org or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pool, err := a.r.GetOrgPoolByID(ctx, orgID, poolID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -410,20 +524,19 @@ func (a *APIController) DeleteOrgPoolHandler(w http.ResponseWriter, r *http.Requ
Error: "Bad Request",
Details: "No org or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.DeleteOrgPool(ctx, orgID, poolID); err != nil {
log.Printf("removing pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /organizations/{orgID}/pools/{poolID} organizations pools UpdateOrgPool
@ -464,28 +577,28 @@ func (a *APIController) UpdateOrgPoolHandler(w http.ResponseWriter, r *http.Requ
Error: "Bad Request",
Details: "No org or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.UpdatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.UpdateOrgPool(ctx, orgID, poolID, poolData)
if err != nil {
log.Printf("error creating organization pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating organization pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -521,28 +634,28 @@ func (a *APIController) InstallOrgWebhookHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var hookParam runnerParams.InstallWebhookParams
if err := json.NewDecoder(r.Body).Decode(&hookParam); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
info, err := a.r.InstallOrgWebhook(ctx, orgID, hookParam)
if err != nil {
log.Printf("installing webhook: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "installing webhook")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -570,14 +683,14 @@ func (a *APIController) UninstallOrgWebhookHandler(w http.ResponseWriter, r *htt
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.UninstallOrgWebhook(ctx, orgID); err != nil {
log.Printf("removing webhook: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing webhook")
handleError(ctx, w, err)
return
}
@ -610,20 +723,20 @@ func (a *APIController) GetOrgWebhookInfoHandler(w http.ResponseWriter, r *http.
Error: "Bad Request",
Details: "No org ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
info, err := a.r.GetOrgWebhookInfo(ctx, orgID)
if err != nil {
log.Printf("getting webhook info: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "getting webhook info")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -16,14 +16,14 @@ package controllers
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
"github.com/gorilla/mux"
)
// swagger:route GET /pools pools ListPools
@ -37,16 +37,15 @@ func (a *APIController) ListAllPoolsHandler(w http.ResponseWriter, r *http.Reque
ctx := r.Context()
pools, err := a.r.ListAllPools(ctx)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pools); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -75,15 +74,15 @@ func (a *APIController) GetPoolByIDHandler(w http.ResponseWriter, r *http.Reques
Error: "Bad Request",
Details: "No pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pool, err := a.r.GetPoolByID(ctx, poolID)
if err != nil {
log.Printf("fetching pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching pool")
handleError(ctx, w, err)
return
}
@ -91,7 +90,7 @@ func (a *APIController) GetPoolByIDHandler(w http.ResponseWriter, r *http.Reques
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -119,14 +118,14 @@ func (a *APIController) DeletePoolByIDHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.DeletePoolByID(ctx, poolID); err != nil {
log.Printf("removing pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing pool")
handleError(ctx, w, err)
return
}
@ -165,27 +164,27 @@ func (a *APIController) UpdatePoolByIDHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.UpdatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.UpdatePoolByID(ctx, poolID, poolData)
if err != nil {
log.Printf("fetching pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -16,15 +16,15 @@ package controllers
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
"github.com/gorilla/mux"
)
// swagger:route POST /repositories repositories CreateRepo
@ -46,20 +46,20 @@ func (a *APIController) CreateRepoHandler(w http.ResponseWriter, r *http.Request
var repoData runnerParams.CreateRepoParams
if err := json.NewDecoder(r.Body).Decode(&repoData); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
repo, err := a.r.CreateRepository(ctx, repoData)
if err != nil {
log.Printf("error creating repository: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating repository")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(repo); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -67,22 +67,46 @@ func (a *APIController) CreateRepoHandler(w http.ResponseWriter, r *http.Request
//
// List repositories.
//
// Parameters:
// + name: owner
// description: Exact owner name to filter by
// type: string
// in: query
// required: false
//
// + name: name
// description: Exact repository name to filter by
// type: string
// in: query
// required: false
//
// + name: endpoint
// description: Exact endpoint name to filter by
// type: string
// in: query
// required: false
//
// Responses:
// 200: Repositories
// default: APIErrorResponse
func (a *APIController) ListReposHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
repos, err := a.r.ListRepositories(ctx)
filter := runnerParams.RepositoryFilter{
Name: r.URL.Query().Get("name"),
Owner: r.URL.Query().Get("owner"),
Endpoint: r.URL.Query().Get("endpoint"),
}
repos, err := a.r.ListRepositories(ctx, filter)
if err != nil {
log.Printf("listing repos: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing repositories")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(repos); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -111,21 +135,21 @@ func (a *APIController) GetRepoByIDHandler(w http.ResponseWriter, r *http.Reques
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
repo, err := a.r.GetRepositoryByID(ctx, repoID)
if err != nil {
log.Printf("fetching repo: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching repository")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(repo); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -159,21 +183,20 @@ func (a *APIController) DeleteRepoHandler(w http.ResponseWriter, r *http.Request
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
keepWebhook, _ := strconv.ParseBool(r.URL.Query().Get("keepWebhook"))
if err := a.r.DeleteRepository(ctx, repoID, keepWebhook); err != nil {
log.Printf("fetching repo: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching repository")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /repositories/{repoID} repositories UpdateRepo
@ -207,27 +230,27 @@ func (a *APIController) UpdateRepoHandler(w http.ResponseWriter, r *http.Request
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var updatePayload runnerParams.UpdateEntityParams
if err := json.NewDecoder(r.Body).Decode(&updatePayload); err != nil {
handleError(w, gErrors.ErrBadRequest)
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
repo, err := a.r.UpdateRepository(ctx, repoID, updatePayload)
if err != nil {
log.Printf("error updating repository: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error updating repository")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(repo); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -262,28 +285,84 @@ func (a *APIController) CreateRepoPoolHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.CreatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.CreateRepoPool(ctx, repoID, poolData)
if err != nil {
log.Printf("error creating repository pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating repository pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route POST /repositories/{repoID}/scalesets repositories scalesets CreateRepoScaleSet
//
// Create repository scale set with the parameters given.
//
// Parameters:
// + name: repoID
// description: Repository ID.
// type: string
// in: path
// required: true
//
// + name: Body
// description: Parameters used when creating the repository scale set.
// type: CreateScaleSetParams
// in: body
// required: true
//
// Responses:
// 200: ScaleSet
// default: APIErrorResponse
func (a *APIController) CreateRepoScaleSetHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
repoID, ok := vars["repoID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var scaleSetData runnerParams.CreateScaleSetParams
if err := json.NewDecoder(r.Body).Decode(&scaleSetData); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
scaleSet, err := a.r.CreateEntityScaleSet(ctx, runnerParams.ForgeEntityTypeRepository, repoID, scaleSetData)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating repository scale set")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSet); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -311,21 +390,63 @@ func (a *APIController) ListRepoPoolsHandler(w http.ResponseWriter, r *http.Requ
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pools, err := a.r.ListRepoPools(ctx, repoID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pools); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /repositories/{repoID}/scalesets repositories scalesets ListRepoScaleSets
//
// List repository scale sets.
//
// Parameters:
// + name: repoID
// description: Repository ID.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ScaleSets
// default: APIErrorResponse
func (a *APIController) ListRepoScaleSetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
repoID, ok := vars["repoID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No repo ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
scaleSets, err := a.r.ListEntityScaleSets(ctx, runnerParams.ForgeEntityTypeRepository, repoID)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing scale sets")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSets); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -360,21 +481,21 @@ func (a *APIController) GetRepoPoolHandler(w http.ResponseWriter, r *http.Reques
Error: "Bad Request",
Details: "No repo or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
pool, err := a.r.GetRepoPoolByID(ctx, repoID, poolID)
if err != nil {
log.Printf("listing pools: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing pools")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -409,20 +530,19 @@ func (a *APIController) DeleteRepoPoolHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No repo or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.DeleteRepoPool(ctx, repoID, poolID); err != nil {
log.Printf("removing pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /repositories/{repoID}/pools/{poolID} repositories pools UpdateRepoPool
@ -463,28 +583,28 @@ func (a *APIController) UpdateRepoPoolHandler(w http.ResponseWriter, r *http.Req
Error: "Bad Request",
Details: "No repo or pool ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var poolData runnerParams.UpdatePoolParams
if err := json.NewDecoder(r.Body).Decode(&poolData); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
pool, err := a.r.UpdateRepoPool(ctx, repoID, poolID, poolData)
if err != nil {
log.Printf("error creating repository pool: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "error creating repository pool")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(pool); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -520,28 +640,28 @@ func (a *APIController) InstallRepoWebhookHandler(w http.ResponseWriter, r *http
Error: "Bad Request",
Details: "No repository ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
var hookParam runnerParams.InstallWebhookParams
if err := json.NewDecoder(r.Body).Decode(&hookParam); err != nil {
log.Printf("failed to decode: %s", err)
handleError(w, gErrors.ErrBadRequest)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
info, err := a.r.InstallRepoWebhook(ctx, repoID, hookParam)
if err != nil {
log.Printf("installing webhook: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "installing webhook")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
@ -569,14 +689,14 @@ func (a *APIController) UninstallRepoWebhookHandler(w http.ResponseWriter, r *ht
Error: "Bad Request",
Details: "No repository ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
if err := a.r.UninstallRepoWebhook(ctx, repoID); err != nil {
log.Printf("removing webhook: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing webhook")
handleError(ctx, w, err)
return
}
@ -609,20 +729,20 @@ func (a *APIController) GetRepoWebhookInfoHandler(w http.ResponseWriter, r *http
Error: "Bad Request",
Details: "No repository ID specified",
}); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
info, err := a.r.GetRepoWebhookInfo(ctx, repoID)
if err != nil {
log.Printf("getting webhook info: %s", err)
handleError(w, err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "getting webhook info")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(info); err != nil {
log.Printf("failed to encode response: %q", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -0,0 +1,211 @@
// Copyright 2022 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package controllers
import (
"encoding/json"
"log/slog"
"net/http"
"strconv"
"github.com/gorilla/mux"
gErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/apiserver/params"
runnerParams "github.com/cloudbase/garm/params"
)
// swagger:route GET /scalesets scalesets ListScalesets
//
// List all scalesets.
//
// Responses:
// 200: ScaleSets
// default: APIErrorResponse
func (a *APIController) ListAllScaleSetsHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
scalesets, err := a.r.ListAllScaleSets(ctx)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "listing scale sets")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scalesets); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route GET /scalesets/{scalesetID} scalesets GetScaleSet
//
// Get scale set by ID.
//
// Parameters:
// + name: scalesetID
// description: ID of the scale set to fetch.
// type: string
// in: path
// required: true
//
// Responses:
// 200: ScaleSet
// default: APIErrorResponse
func (a *APIController) GetScaleSetByIDHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
scaleSetID, ok := vars["scalesetID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No scale set ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
id, err := strconv.ParseUint(scaleSetID, 10, 32)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
scaleSet, err := a.r.GetScaleSetByID(ctx, uint(id))
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "fetching scale set")
handleError(ctx, w, err)
return
}
scaleSet.RunnerBootstrapTimeout = scaleSet.RunnerTimeout()
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSet); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
// swagger:route DELETE /scalesets/{scalesetID} scalesets DeleteScaleSet
//
// Delete scale set by ID.
//
// Parameters:
// + name: scalesetID
// description: ID of the scale set to delete.
// type: string
// in: path
// required: true
//
// Responses:
// default: APIErrorResponse
func (a *APIController) DeleteScaleSetByIDHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
scalesetID, ok := vars["scalesetID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No scale set ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
id, err := strconv.ParseUint(scalesetID, 10, 32)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
if err := a.r.DeleteScaleSetByID(ctx, uint(id)); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "removing scale set")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
}
// swagger:route PUT /scalesets/{scalesetID} scalesets UpdateScaleSet
//
// Update scale set by ID.
//
// Parameters:
// + name: scalesetID
// description: ID of the scale set to update.
// type: string
// in: path
// required: true
//
// + name: Body
// description: Parameters to update the scale set with.
// type: UpdateScaleSetParams
// in: body
// required: true
//
// Responses:
// 200: ScaleSet
// default: APIErrorResponse
func (a *APIController) UpdateScaleSetByIDHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
vars := mux.Vars(r)
scalesetID, ok := vars["scalesetID"]
if !ok {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(params.APIErrorResponse{
Error: "Bad Request",
Details: "No scale set ID specified",
}); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
id, err := strconv.ParseUint(scalesetID, 10, 32)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to parse id")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
var scaleSetData runnerParams.UpdateScaleSetParams
if err := json.NewDecoder(r.Body).Decode(&scaleSetData); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to decode")
handleError(ctx, w, gErrors.ErrBadRequest)
return
}
scaleSet, err := a.r.UpdateScaleSetByID(ctx, uint(id), scaleSetData)
if err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "updating scale set")
handleError(ctx, w, err)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(scaleSet); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}

View file

@ -14,6 +14,7 @@
package params
// swagger:model APIErrorResponse
// APIErrorResponse holds information about an error, returned by the API
type APIErrorResponse struct {
Error string `json:"error"`
@ -36,4 +37,9 @@ var (
Error: "init_required",
Details: "Missing superuser",
}
// URLsRequired is returned if the controller does not have the required URLs
URLsRequired = APIErrorResponse{
Error: "urls_required",
Details: "Missing required URLs. Make sure you update the metadata and callback URLs",
}
)

View file

@ -40,23 +40,25 @@
// swagger:meta
package routers
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 generate spec --input=../swagger-models.yaml --output=../swagger.yaml --include="routers|controllers"
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 validate ../swagger.yaml
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 generate spec --input=../swagger-models.yaml --output=../swagger.yaml --include="routers|controllers"
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 validate ../swagger.yaml
//go:generate rm -rf ../../client
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 generate client --target=../../ --spec=../swagger.yaml
//go:generate go run github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0 generate client --target=../../ --spec=../swagger.yaml
import (
_ "expvar" // Register the expvar handlers
"io"
"log/slog"
"net/http"
_ "net/http/pprof" // Register the pprof handlers
_ "net/http/pprof" //nolint:golangci-lint,gosec // Register the pprof handlers
"github.com/felixge/httpsnoop"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/cloudbase/garm-provider-common/util"
"github.com/cloudbase/garm/apiserver/controllers"
"github.com/cloudbase/garm/auth"
"github.com/cloudbase/garm/config"
spaAssets "github.com/cloudbase/garm/webapp/assets"
)
func WithMetricsRouter(parentRouter *mux.Router, disableAuth bool, metricsMiddlerware auth.Middleware) *mux.Router {
@ -82,10 +84,51 @@ func WithDebugServer(parentRouter *mux.Router) *mux.Router {
return parentRouter
}
func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddleware, initMiddleware, instanceMiddleware auth.Middleware, manageWebhooks bool) *mux.Router {
func WithWebUI(parentRouter *mux.Router, apiConfig config.APIServer) *mux.Router {
if parentRouter == nil {
return nil
}
if apiConfig.WebUI.EnableWebUI {
slog.Info("WebUI is enabled, adding webapp routes")
webappPath := apiConfig.WebUI.GetWebappPath()
slog.Info("Using webapp path", "path", webappPath)
// Accessing / should redirect to the UI
parentRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, webappPath, http.StatusMovedPermanently) // 301
})
// Serve the SPA with dynamic path
parentRouter.PathPrefix(webappPath).HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
spaAssets.ServeSPAWithPath(w, r, webappPath)
}).Methods("GET")
} else {
slog.Info("WebUI is disabled, skipping webapp routes")
}
return parentRouter
}
func requestLogger(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// gathers metrics from the upstream handlers
metrics := httpsnoop.CaptureMetrics(h, w, r)
slog.Info(
"access_log",
slog.String("method", r.Method),
slog.String("uri", r.URL.RequestURI()),
slog.String("user_agent", r.Header.Get("User-Agent")),
slog.String("ip", r.RemoteAddr),
slog.Int("code", metrics.Code),
slog.Int64("bytes", metrics.Written),
slog.Duration("request_time", metrics.Duration),
)
})
}
func NewAPIRouter(han *controllers.APIController, authMiddleware, initMiddleware, urlsRequiredMiddleware, instanceMiddleware auth.Middleware, manageWebhooks bool) *mux.Router {
router := mux.NewRouter()
logMiddleware := util.NewLoggingMiddleware(logWriter)
router.Use(logMiddleware)
router.Use(requestLogger)
// Handles github webhooks
webhookRouter := router.PathPrefix("/webhooks").Subrouter()
@ -106,6 +149,8 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
callbackRouter := apiSubRouter.PathPrefix("/callbacks").Subrouter()
callbackRouter.Handle("/status/", http.HandlerFunc(han.InstanceStatusMessageHandler)).Methods("POST", "OPTIONS")
callbackRouter.Handle("/status", http.HandlerFunc(han.InstanceStatusMessageHandler)).Methods("POST", "OPTIONS")
callbackRouter.Handle("/system-info/", http.HandlerFunc(han.InstanceSystemInfoHandler)).Methods("POST", "OPTIONS")
callbackRouter.Handle("/system-info", http.HandlerFunc(han.InstanceSystemInfoHandler)).Methods("POST", "OPTIONS")
callbackRouter.Use(instanceMiddleware.Middleware)
///////////////////
@ -133,11 +178,38 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
authRouter.Handle("/{login:login\\/?}", http.HandlerFunc(han.LoginHandler)).Methods("POST", "OPTIONS")
authRouter.Use(initMiddleware.Middleware)
//////////////////////////
// Controller endpoints //
//////////////////////////
controllerRouter := apiSubRouter.PathPrefix("/controller").Subrouter()
// The controller endpoints allow us to get information about the controller and update the URL endpoints.
// This endpoint must not be guarded by the urlsRequiredMiddleware as that would prevent the user from
// updating the URLs.
controllerRouter.Use(initMiddleware.Middleware)
controllerRouter.Use(authMiddleware.Middleware)
controllerRouter.Use(auth.AdminRequiredMiddleware)
// Get controller info
controllerRouter.Handle("/", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
controllerRouter.Handle("", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
// Update controller
controllerRouter.Handle("/", http.HandlerFunc(han.UpdateControllerHandler)).Methods("PUT", "OPTIONS")
controllerRouter.Handle("", http.HandlerFunc(han.UpdateControllerHandler)).Methods("PUT", "OPTIONS")
////////////////////////////////////
// API router for everything else //
////////////////////////////////////
apiRouter := apiSubRouter.PathPrefix("").Subrouter()
apiRouter.Use(initMiddleware.Middleware)
// all endpoints except the controller endpoint should return an error
// if the required metadata, callback and webhook URLs are not set.
apiRouter.Use(urlsRequiredMiddleware.Middleware)
apiRouter.Use(authMiddleware.Middleware)
apiRouter.Use(auth.AdminRequiredMiddleware)
// Legacy controller path
apiRouter.Handle("/controller-info/", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/controller-info", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
// Metrics Token
apiRouter.Handle("/metrics-token/", http.HandlerFunc(han.MetricsTokenHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/metrics-token", http.HandlerFunc(han.MetricsTokenHandler)).Methods("GET", "OPTIONS")
@ -168,6 +240,25 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/pools/{poolID}/instances/", http.HandlerFunc(han.ListPoolInstancesHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/pools/{poolID}/instances", http.HandlerFunc(han.ListPoolInstancesHandler)).Methods("GET", "OPTIONS")
////////////////
// Scale sets //
////////////////
// List all pools
apiRouter.Handle("/scalesets/", http.HandlerFunc(han.ListAllScaleSetsHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/scalesets", http.HandlerFunc(han.ListAllScaleSetsHandler)).Methods("GET", "OPTIONS")
// Get one pool
apiRouter.Handle("/scalesets/{scalesetID}/", http.HandlerFunc(han.GetScaleSetByIDHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/scalesets/{scalesetID}", http.HandlerFunc(han.GetScaleSetByIDHandler)).Methods("GET", "OPTIONS")
// Delete one pool
apiRouter.Handle("/scalesets/{scalesetID}/", http.HandlerFunc(han.DeleteScaleSetByIDHandler)).Methods("DELETE", "OPTIONS")
apiRouter.Handle("/scalesets/{scalesetID}", http.HandlerFunc(han.DeleteScaleSetByIDHandler)).Methods("DELETE", "OPTIONS")
// Update one pool
apiRouter.Handle("/scalesets/{scalesetID}/", http.HandlerFunc(han.UpdateScaleSetByIDHandler)).Methods("PUT", "OPTIONS")
apiRouter.Handle("/scalesets/{scalesetID}", http.HandlerFunc(han.UpdateScaleSetByIDHandler)).Methods("PUT", "OPTIONS")
// List pool instances
apiRouter.Handle("/scalesets/{scalesetID}/instances/", http.HandlerFunc(han.ListScaleSetInstancesHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/scalesets/{scalesetID}/instances", http.HandlerFunc(han.ListScaleSetInstancesHandler)).Methods("GET", "OPTIONS")
/////////////
// Runners //
/////////////
@ -200,6 +291,14 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/repositories/{repoID}/pools/", http.HandlerFunc(han.CreateRepoPoolHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/repositories/{repoID}/pools", http.HandlerFunc(han.CreateRepoPoolHandler)).Methods("POST", "OPTIONS")
// Create scale set
apiRouter.Handle("/repositories/{repoID}/scalesets/", http.HandlerFunc(han.CreateRepoScaleSetHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/repositories/{repoID}/scalesets", http.HandlerFunc(han.CreateRepoScaleSetHandler)).Methods("POST", "OPTIONS")
// List scale sets
apiRouter.Handle("/repositories/{repoID}/scalesets/", http.HandlerFunc(han.ListRepoScaleSetsHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/repositories/{repoID}/scalesets", http.HandlerFunc(han.ListRepoScaleSetsHandler)).Methods("GET", "OPTIONS")
// Repo instances list
apiRouter.Handle("/repositories/{repoID}/instances/", http.HandlerFunc(han.ListRepoInstancesHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/repositories/{repoID}/instances", http.HandlerFunc(han.ListRepoInstancesHandler)).Methods("GET", "OPTIONS")
@ -250,6 +349,14 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/organizations/{orgID}/pools/", http.HandlerFunc(han.CreateOrgPoolHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/organizations/{orgID}/pools", http.HandlerFunc(han.CreateOrgPoolHandler)).Methods("POST", "OPTIONS")
// Create org scale set
apiRouter.Handle("/organizations/{orgID}/scalesets/", http.HandlerFunc(han.CreateOrgScaleSetHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/organizations/{orgID}/scalesets", http.HandlerFunc(han.CreateOrgScaleSetHandler)).Methods("POST", "OPTIONS")
// List org scale sets
apiRouter.Handle("/organizations/{orgID}/scalesets/", http.HandlerFunc(han.ListOrgScaleSetsHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/organizations/{orgID}/scalesets", http.HandlerFunc(han.ListOrgScaleSetsHandler)).Methods("GET", "OPTIONS")
// Org instances list
apiRouter.Handle("/organizations/{orgID}/instances/", http.HandlerFunc(han.ListOrgInstancesHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/organizations/{orgID}/instances", http.HandlerFunc(han.ListOrgInstancesHandler)).Methods("GET", "OPTIONS")
@ -300,6 +407,14 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/enterprises/{enterpriseID}/pools/", http.HandlerFunc(han.CreateEnterprisePoolHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/enterprises/{enterpriseID}/pools", http.HandlerFunc(han.CreateEnterprisePoolHandler)).Methods("POST", "OPTIONS")
// Create enterprise scale sets
apiRouter.Handle("/enterprises/{enterpriseID}/scalesets/", http.HandlerFunc(han.CreateEnterpriseScaleSetHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/enterprises/{enterpriseID}/scalesets", http.HandlerFunc(han.CreateEnterpriseScaleSetHandler)).Methods("POST", "OPTIONS")
// List enterprise scale sets
apiRouter.Handle("/enterprises/{enterpriseID}/scalesets/", http.HandlerFunc(han.ListEnterpriseScaleSetsHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/enterprises/{enterpriseID}/scalesets", http.HandlerFunc(han.ListEnterpriseScaleSetsHandler)).Methods("GET", "OPTIONS")
// Enterprise instances list
apiRouter.Handle("/enterprises/{enterpriseID}/instances/", http.HandlerFunc(han.ListEnterpriseInstancesHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/enterprises/{enterpriseID}/instances", http.HandlerFunc(han.ListEnterpriseInstancesHandler)).Methods("GET", "OPTIONS")
@ -320,20 +435,103 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl
apiRouter.Handle("/enterprises/", http.HandlerFunc(han.CreateEnterpriseHandler)).Methods("POST", "OPTIONS")
apiRouter.Handle("/enterprises", http.HandlerFunc(han.CreateEnterpriseHandler)).Methods("POST", "OPTIONS")
// Credentials and providers
apiRouter.Handle("/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
apiRouter.Handle("/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
// Providers
apiRouter.Handle("/providers/", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
apiRouter.Handle("/providers", http.HandlerFunc(han.ListProviders)).Methods("GET", "OPTIONS")
// Controller info
apiRouter.Handle("/controller-info/", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
apiRouter.Handle("/controller-info", http.HandlerFunc(han.ControllerInfoHandler)).Methods("GET", "OPTIONS")
//////////////////////
// Github Endpoints //
//////////////////////
// Create Github Endpoint
apiRouter.Handle("/github/endpoints/", http.HandlerFunc(han.CreateGithubEndpoint)).Methods("POST", "OPTIONS")
apiRouter.Handle("/github/endpoints", http.HandlerFunc(han.CreateGithubEndpoint)).Methods("POST", "OPTIONS")
// List Github Endpoints
apiRouter.Handle("/github/endpoints/", http.HandlerFunc(han.ListGithubEndpoints)).Methods("GET", "OPTIONS")
apiRouter.Handle("/github/endpoints", http.HandlerFunc(han.ListGithubEndpoints)).Methods("GET", "OPTIONS")
// Get Github Endpoint
apiRouter.Handle("/github/endpoints/{name}/", http.HandlerFunc(han.GetGithubEndpoint)).Methods("GET", "OPTIONS")
apiRouter.Handle("/github/endpoints/{name}", http.HandlerFunc(han.GetGithubEndpoint)).Methods("GET", "OPTIONS")
// Delete Github Endpoint
apiRouter.Handle("/github/endpoints/{name}/", http.HandlerFunc(han.DeleteGithubEndpoint)).Methods("DELETE", "OPTIONS")
apiRouter.Handle("/github/endpoints/{name}", http.HandlerFunc(han.DeleteGithubEndpoint)).Methods("DELETE", "OPTIONS")
// Update Github Endpoint
apiRouter.Handle("/github/endpoints/{name}/", http.HandlerFunc(han.UpdateGithubEndpoint)).Methods("PUT", "OPTIONS")
apiRouter.Handle("/github/endpoints/{name}", http.HandlerFunc(han.UpdateGithubEndpoint)).Methods("PUT", "OPTIONS")
// Websocket log writer
apiRouter.Handle("/{ws:ws\\/?}", http.HandlerFunc(han.WSHandler)).Methods("GET")
////////////////////////
// Github credentials //
////////////////////////
// Legacy credentials path
apiRouter.Handle("/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
apiRouter.Handle("/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
// List Github Credentials
apiRouter.Handle("/github/credentials/", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
apiRouter.Handle("/github/credentials", http.HandlerFunc(han.ListCredentials)).Methods("GET", "OPTIONS")
// Create Github Credentials
apiRouter.Handle("/github/credentials/", http.HandlerFunc(han.CreateGithubCredential)).Methods("POST", "OPTIONS")
apiRouter.Handle("/github/credentials", http.HandlerFunc(han.CreateGithubCredential)).Methods("POST", "OPTIONS")
// Get Github Credential
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.GetGithubCredential)).Methods("GET", "OPTIONS")
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.GetGithubCredential)).Methods("GET", "OPTIONS")
// Delete Github Credential
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.DeleteGithubCredential)).Methods("DELETE", "OPTIONS")
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.DeleteGithubCredential)).Methods("DELETE", "OPTIONS")
// Update Github Credential
apiRouter.Handle("/github/credentials/{id}/", http.HandlerFunc(han.UpdateGithubCredential)).Methods("PUT", "OPTIONS")
apiRouter.Handle("/github/credentials/{id}", http.HandlerFunc(han.UpdateGithubCredential)).Methods("PUT", "OPTIONS")
// NotFound handler
//////////////////////
// Gitea Endpoints //
//////////////////////
// Create Gitea Endpoint
apiRouter.Handle("/gitea/endpoints/", http.HandlerFunc(han.CreateGiteaEndpoint)).Methods("POST", "OPTIONS")
apiRouter.Handle("/gitea/endpoints", http.HandlerFunc(han.CreateGiteaEndpoint)).Methods("POST", "OPTIONS")
// List Gitea Endpoints
apiRouter.Handle("/gitea/endpoints/", http.HandlerFunc(han.ListGiteaEndpoints)).Methods("GET", "OPTIONS")
apiRouter.Handle("/gitea/endpoints", http.HandlerFunc(han.ListGiteaEndpoints)).Methods("GET", "OPTIONS")
// Get Gitea Endpoint
apiRouter.Handle("/gitea/endpoints/{name}/", http.HandlerFunc(han.GetGiteaEndpoint)).Methods("GET", "OPTIONS")
apiRouter.Handle("/gitea/endpoints/{name}", http.HandlerFunc(han.GetGiteaEndpoint)).Methods("GET", "OPTIONS")
// Delete Gitea Endpoint
apiRouter.Handle("/gitea/endpoints/{name}/", http.HandlerFunc(han.DeleteGiteaEndpoint)).Methods("DELETE", "OPTIONS")
apiRouter.Handle("/gitea/endpoints/{name}", http.HandlerFunc(han.DeleteGiteaEndpoint)).Methods("DELETE", "OPTIONS")
// Update Gitea Endpoint
apiRouter.Handle("/gitea/endpoints/{name}/", http.HandlerFunc(han.UpdateGiteaEndpoint)).Methods("PUT", "OPTIONS")
apiRouter.Handle("/gitea/endpoints/{name}", http.HandlerFunc(han.UpdateGiteaEndpoint)).Methods("PUT", "OPTIONS")
////////////////////////
// Gitea credentials //
////////////////////////
// List Gitea Credentials
apiRouter.Handle("/gitea/credentials/", http.HandlerFunc(han.ListGiteaCredentials)).Methods("GET", "OPTIONS")
apiRouter.Handle("/gitea/credentials", http.HandlerFunc(han.ListGiteaCredentials)).Methods("GET", "OPTIONS")
// Create Gitea Credentials
apiRouter.Handle("/gitea/credentials/", http.HandlerFunc(han.CreateGiteaCredential)).Methods("POST", "OPTIONS")
apiRouter.Handle("/gitea/credentials", http.HandlerFunc(han.CreateGiteaCredential)).Methods("POST", "OPTIONS")
// Get Gitea Credential
apiRouter.Handle("/gitea/credentials/{id}/", http.HandlerFunc(han.GetGiteaCredential)).Methods("GET", "OPTIONS")
apiRouter.Handle("/gitea/credentials/{id}", http.HandlerFunc(han.GetGiteaCredential)).Methods("GET", "OPTIONS")
// Delete Gitea Credential
apiRouter.Handle("/gitea/credentials/{id}/", http.HandlerFunc(han.DeleteGiteaCredential)).Methods("DELETE", "OPTIONS")
apiRouter.Handle("/gitea/credentials/{id}", http.HandlerFunc(han.DeleteGiteaCredential)).Methods("DELETE", "OPTIONS")
// Update Gitea Credential
apiRouter.Handle("/gitea/credentials/{id}/", http.HandlerFunc(han.UpdateGiteaCredential)).Methods("PUT", "OPTIONS")
apiRouter.Handle("/gitea/credentials/{id}", http.HandlerFunc(han.UpdateGiteaCredential)).Methods("PUT", "OPTIONS")
/////////////////////////
// Websocket endpoints //
/////////////////////////
// Legacy log websocket path
apiRouter.Handle("/ws/", http.HandlerFunc(han.WSHandler)).Methods("GET")
apiRouter.Handle("/ws", http.HandlerFunc(han.WSHandler)).Methods("GET")
// Log websocket endpoint
apiRouter.Handle("/ws/logs/", http.HandlerFunc(han.WSHandler)).Methods("GET")
apiRouter.Handle("/ws/logs", http.HandlerFunc(han.WSHandler)).Methods("GET")
// DB watcher websocket endpoint
apiRouter.Handle("/ws/events/", http.HandlerFunc(han.EventsHandler)).Methods("GET")
apiRouter.Handle("/ws/events", http.HandlerFunc(han.EventsHandler)).Methods("GET")
// NotFound handler - this should be last
apiRouter.PathPrefix("/").HandlerFunc(han.NotFoundHandler).Methods("GET", "POST", "PUT", "DELETE", "OPTIONS")
return router
}

View file

@ -74,11 +74,11 @@ definitions:
package: github.com/cloudbase/garm/params
alias: garm_params
items:
$ref: '#/definitions/GithubCredentials'
GithubCredentials:
$ref: '#/definitions/ForgeCredentials'
ForgeCredentials:
type: object
x-go-type:
type: GithubCredentials
type: ForgeCredentials
import:
package: github.com/cloudbase/garm/params
alias: garm_params
@ -130,6 +130,22 @@ definitions:
import:
package: github.com/cloudbase/garm/params
alias: garm_params
ScaleSets:
type: array
x-go-type:
type: ScaleSets
import:
package: github.com/cloudbase/garm/params
alias: garm_params
items:
$ref: '#/definitions/ScaleSet'
ScaleSet:
type: object
x-go-type:
type: ScaleSet
import:
package: github.com/cloudbase/garm/params
alias: garm_params
Repositories:
type: array
x-go-type:
@ -213,6 +229,13 @@ definitions:
import:
package: github.com/cloudbase/garm/params
alias: garm_params
CreateScaleSetParams:
type: object
x-go-type:
type: CreateScaleSetParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdatePoolParams:
type: object
x-go-type:
@ -220,6 +243,13 @@ definitions:
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateScaleSetParams:
type: object
x-go-type:
type: UpdateScaleSetParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
APIErrorResponse:
type: object
x-go-type:
@ -227,3 +257,89 @@ definitions:
import:
package: github.com/cloudbase/garm/apiserver/params
alias: apiserver_params
CreateInstanceParams:
type: object
x-go-type:
type: CreateInstanceParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateGithubEndpointParams:
type: object
x-go-type:
type: UpdateGithubEndpointParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateGiteaEndpointParams:
type: object
x-go-type:
type: UpdateGiteaEndpointParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
ForgeEndpoint:
type: object
x-go-type:
type: ForgeEndpoint
import:
package: github.com/cloudbase/garm/params
alias: garm_params
ForgeEndpoints:
type: array
x-go-type:
type: ForgeEndpoints
import:
package: github.com/cloudbase/garm/params
alias: garm_params
items:
$ref: '#/definitions/ForgeEndpoint'
CreateGithubEndpointParams:
type: object
x-go-type:
type: CreateGithubEndpointParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
CreateGiteaEndpointParams:
type: object
x-go-type:
type: CreateGiteaEndpointParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
CreateGithubCredentialsParams:
type: object
x-go-type:
type: CreateGithubCredentialsParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
CreateGiteaCredentialsParams:
type: object
x-go-type:
type: CreateGiteaCredentialsParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateGithubCredentialsParams:
type: object
x-go-type:
type: UpdateGithubCredentialsParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateGiteaCredentialsParams:
type: object
x-go-type:
type: UpdateGiteaCredentialsParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params
UpdateControllerParams:
type: object
x-go-type:
type: UpdateControllerParams
import:
package: github.com/cloudbase/garm/params
alias: garm_params

View file

@ -23,6 +23,41 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateEnterpriseParams
CreateGiteaCredentialsParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateGiteaCredentialsParams
CreateGiteaEndpointParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateGiteaEndpointParams
CreateGithubCredentialsParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateGithubCredentialsParams
CreateGithubEndpointParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateGithubEndpointParams
CreateInstanceParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateInstanceParams
CreateOrgParams:
type: object
x-go-type:
@ -44,9 +79,16 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateRepoParams
CreateScaleSetParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: CreateScaleSetParams
Credentials:
items:
$ref: '#/definitions/GithubCredentials'
$ref: '#/definitions/ForgeCredentials'
type: array
x-go-type:
import:
@ -69,13 +111,29 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: Enterprises
GithubCredentials:
ForgeCredentials:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: GithubCredentials
type: ForgeCredentials
ForgeEndpoint:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: ForgeEndpoint
ForgeEndpoints:
items:
$ref: '#/definitions/ForgeEndpoint'
type: array
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: ForgeEndpoints
HookInfo:
type: object
x-go-type:
@ -207,6 +265,29 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: Repository
ScaleSet:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: ScaleSet
ScaleSets:
items:
$ref: '#/definitions/ScaleSet'
type: array
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: ScaleSets
UpdateControllerParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateControllerParams
UpdateEntityParams:
type: object
x-go-type:
@ -214,6 +295,34 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateEntityParams
UpdateGiteaCredentialsParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateGiteaCredentialsParams
UpdateGiteaEndpointParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateGiteaEndpointParams
UpdateGithubCredentialsParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateGithubCredentialsParams
UpdateGithubEndpointParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateGithubEndpointParams
UpdatePoolParams:
type: object
x-go-type:
@ -221,6 +330,13 @@ definitions:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdatePoolParams
UpdateScaleSetParams:
type: object
x-go-type:
import:
alias: garm_params
package: github.com/cloudbase/garm/params
type: UpdateScaleSetParams
User:
type: object
x-go-type:
@ -260,6 +376,30 @@ paths:
summary: Logs in a user and returns a JWT token.
tags:
- login
/controller:
put:
operationId: UpdateController
parameters:
- description: Parameters used when updating the controller.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateControllerParams'
description: Parameters used when updating the controller.
type: object
responses:
"200":
description: ControllerInfo
schema:
$ref: '#/definitions/ControllerInfo'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update controller.
tags:
- controller
/controller-info:
get:
operationId: ControllerInfo
@ -275,24 +415,18 @@ paths:
summary: Get controller info.
tags:
- controllerInfo
/credentials:
get:
operationId: ListCredentials
responses:
"200":
description: Credentials
schema:
$ref: '#/definitions/Credentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all credentials.
tags:
- credentials
/enterprises:
get:
operationId: ListEnterprises
parameters:
- description: Exact enterprise name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses:
"200":
description: Enterprises
@ -549,6 +683,57 @@ paths:
tags:
- enterprises
- pools
/enterprises/{enterpriseID}/scalesets:
get:
operationId: ListEnterpriseScaleSets
parameters:
- description: Enterprise ID.
in: path
name: enterpriseID
required: true
type: string
responses:
"200":
description: ScaleSets
schema:
$ref: '#/definitions/ScaleSets'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List enterprise scale sets.
tags:
- enterprises
- scalesets
post:
operationId: CreateEnterpriseScaleSet
parameters:
- description: Enterprise ID.
in: path
name: enterpriseID
required: true
type: string
- description: Parameters used when creating the enterprise scale set.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateScaleSetParams'
description: Parameters used when creating the enterprise scale set.
type: object
responses:
"200":
description: ScaleSet
schema:
$ref: '#/definitions/ScaleSet'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create enterprise pool with the parameters given.
tags:
- enterprises
- scalesets
/first-run:
post:
operationId: FirstRun
@ -573,6 +758,418 @@ paths:
summary: Initialize the first run of the controller.
tags:
- first-run
/gitea/credentials:
get:
operationId: ListGiteaCredentials
responses:
"200":
description: Credentials
schema:
$ref: '#/definitions/Credentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all credentials.
tags:
- credentials
post:
operationId: CreateGiteaCredentials
parameters:
- description: Parameters used when creating a Gitea credential.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateGiteaCredentialsParams'
description: Parameters used when creating a Gitea credential.
type: object
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create a Gitea credential.
tags:
- credentials
/gitea/credentials/{id}:
delete:
operationId: DeleteGiteaCredentials
parameters:
- description: ID of the Gitea credential.
in: path
name: id
required: true
type: integer
responses:
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Delete a Gitea credential.
tags:
- credentials
get:
operationId: GetGiteaCredentials
parameters:
- description: ID of the Gitea credential.
in: path
name: id
required: true
type: integer
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get a Gitea credential.
tags:
- credentials
put:
operationId: UpdateGiteaCredentials
parameters:
- description: ID of the Gitea credential.
in: path
name: id
required: true
type: integer
- description: Parameters used when updating a Gitea credential.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateGiteaCredentialsParams'
description: Parameters used when updating a Gitea credential.
type: object
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update a Gitea credential.
tags:
- credentials
/gitea/endpoints:
get:
operationId: ListGiteaEndpoints
responses:
"200":
description: ForgeEndpoints
schema:
$ref: '#/definitions/ForgeEndpoints'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all Gitea Endpoints.
tags:
- endpoints
post:
operationId: CreateGiteaEndpoint
parameters:
- description: Parameters used when creating a Gitea endpoint.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateGiteaEndpointParams'
description: Parameters used when creating a Gitea endpoint.
type: object
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create a Gitea Endpoint.
tags:
- endpoints
/gitea/endpoints/{name}:
delete:
operationId: DeleteGiteaEndpoint
parameters:
- description: The name of the Gitea endpoint.
in: path
name: name
required: true
type: string
responses:
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Delete a Gitea Endpoint.
tags:
- endpoints
get:
operationId: GetGiteaEndpoint
parameters:
- description: The name of the Gitea endpoint.
in: path
name: name
required: true
type: string
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get a Gitea Endpoint.
tags:
- endpoints
put:
operationId: UpdateGiteaEndpoint
parameters:
- description: The name of the Gitea endpoint.
in: path
name: name
required: true
type: string
- description: Parameters used when updating a Gitea endpoint.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateGiteaEndpointParams'
description: Parameters used when updating a Gitea endpoint.
type: object
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update a Gitea Endpoint.
tags:
- endpoints
/github/credentials:
get:
operationId: ListCredentials
responses:
"200":
description: Credentials
schema:
$ref: '#/definitions/Credentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all credentials.
tags:
- credentials
post:
operationId: CreateCredentials
parameters:
- description: Parameters used when creating a GitHub credential.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateGithubCredentialsParams'
description: Parameters used when creating a GitHub credential.
type: object
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create a GitHub credential.
tags:
- credentials
/github/credentials/{id}:
delete:
operationId: DeleteCredentials
parameters:
- description: ID of the GitHub credential.
in: path
name: id
required: true
type: integer
responses:
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Delete a GitHub credential.
tags:
- credentials
get:
operationId: GetCredentials
parameters:
- description: ID of the GitHub credential.
in: path
name: id
required: true
type: integer
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get a GitHub credential.
tags:
- credentials
put:
operationId: UpdateCredentials
parameters:
- description: ID of the GitHub credential.
in: path
name: id
required: true
type: integer
- description: Parameters used when updating a GitHub credential.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateGithubCredentialsParams'
description: Parameters used when updating a GitHub credential.
type: object
responses:
"200":
description: ForgeCredentials
schema:
$ref: '#/definitions/ForgeCredentials'
"400":
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update a GitHub credential.
tags:
- credentials
/github/endpoints:
get:
operationId: ListGithubEndpoints
responses:
"200":
description: ForgeEndpoints
schema:
$ref: '#/definitions/ForgeEndpoints'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all GitHub Endpoints.
tags:
- endpoints
post:
operationId: CreateGithubEndpoint
parameters:
- description: Parameters used when creating a GitHub endpoint.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateGithubEndpointParams'
description: Parameters used when creating a GitHub endpoint.
type: object
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create a GitHub Endpoint.
tags:
- endpoints
/github/endpoints/{name}:
delete:
operationId: DeleteGithubEndpoint
parameters:
- description: The name of the GitHub endpoint.
in: path
name: name
required: true
type: string
responses:
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Delete a GitHub Endpoint.
tags:
- endpoints
get:
operationId: GetGithubEndpoint
parameters:
- description: The name of the GitHub endpoint.
in: path
name: name
required: true
type: string
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get a GitHub Endpoint.
tags:
- endpoints
put:
operationId: UpdateGithubEndpoint
parameters:
- description: The name of the GitHub endpoint.
in: path
name: name
required: true
type: string
- description: Parameters used when updating a GitHub endpoint.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateGithubEndpointParams'
description: Parameters used when updating a GitHub endpoint.
type: object
responses:
"200":
description: ForgeEndpoint
schema:
$ref: '#/definitions/ForgeEndpoint'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update a GitHub Endpoint.
tags:
- endpoints
/instances:
get:
operationId: ListInstances
@ -601,6 +1198,10 @@ paths:
in: query
name: forceRemove
type: boolean
- description: If true GARM will ignore unauthorized errors returned by GitHub when removing a runner. This is useful if you want to clean up runners and your credentials have expired.
in: query
name: bypassGHUnauthorized
type: boolean
responses:
default:
description: APIErrorResponse
@ -662,6 +1263,15 @@ paths:
/organizations:
get:
operationId: ListOrgs
parameters:
- description: Exact organization name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses:
"200":
description: Organizations
@ -922,6 +1532,57 @@ paths:
tags:
- organizations
- pools
/organizations/{orgID}/scalesets:
get:
operationId: ListOrgScaleSets
parameters:
- description: Organization ID.
in: path
name: orgID
required: true
type: string
responses:
"200":
description: ScaleSets
schema:
$ref: '#/definitions/ScaleSets'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List organization scale sets.
tags:
- organizations
- scalesets
post:
operationId: CreateOrgScaleSet
parameters:
- description: Organization ID.
in: path
name: orgID
required: true
type: string
- description: Parameters used when creating the organization scale set.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateScaleSetParams'
description: Parameters used when creating the organization scale set.
type: object
responses:
"200":
description: ScaleSet
schema:
$ref: '#/definitions/ScaleSet'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create organization scale set with the parameters given.
tags:
- organizations
- scalesets
/organizations/{orgID}/webhook:
delete:
operationId: UninstallOrgWebhook
@ -1111,6 +1772,19 @@ paths:
/repositories:
get:
operationId: ListRepos
parameters:
- description: Exact owner name to filter by
in: query
name: owner
type: string
- description: Exact repository name to filter by
in: query
name: name
type: string
- description: Exact endpoint name to filter by
in: query
name: endpoint
type: string
responses:
"200":
description: Repositories
@ -1371,6 +2045,57 @@ paths:
tags:
- repositories
- pools
/repositories/{repoID}/scalesets:
get:
operationId: ListRepoScaleSets
parameters:
- description: Repository ID.
in: path
name: repoID
required: true
type: string
responses:
"200":
description: ScaleSets
schema:
$ref: '#/definitions/ScaleSets'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List repository scale sets.
tags:
- repositories
- scalesets
post:
operationId: CreateRepoScaleSet
parameters:
- description: Repository ID.
in: path
name: repoID
required: true
type: string
- description: Parameters used when creating the repository scale set.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/CreateScaleSetParams'
description: Parameters used when creating the repository scale set.
type: object
responses:
"200":
description: ScaleSet
schema:
$ref: '#/definitions/ScaleSet'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Create repository scale set with the parameters given.
tags:
- repositories
- scalesets
/repositories/{repoID}/webhook:
delete:
operationId: UninstallRepoWebhook
@ -1441,6 +2166,107 @@ paths:
tags:
- repositories
- hooks
/scalesets:
get:
operationId: ListScalesets
responses:
"200":
description: ScaleSets
schema:
$ref: '#/definitions/ScaleSets'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List all scalesets.
tags:
- scalesets
/scalesets/{scalesetID}:
delete:
operationId: DeleteScaleSet
parameters:
- description: ID of the scale set to delete.
in: path
name: scalesetID
required: true
type: string
responses:
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Delete scale set by ID.
tags:
- scalesets
get:
operationId: GetScaleSet
parameters:
- description: ID of the scale set to fetch.
in: path
name: scalesetID
required: true
type: string
responses:
"200":
description: ScaleSet
schema:
$ref: '#/definitions/ScaleSet'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Get scale set by ID.
tags:
- scalesets
put:
operationId: UpdateScaleSet
parameters:
- description: ID of the scale set to update.
in: path
name: scalesetID
required: true
type: string
- description: Parameters to update the scale set with.
in: body
name: Body
required: true
schema:
$ref: '#/definitions/UpdateScaleSetParams'
description: Parameters to update the scale set with.
type: object
responses:
"200":
description: ScaleSet
schema:
$ref: '#/definitions/ScaleSet'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: Update scale set by ID.
tags:
- scalesets
/scalesets/{scalesetID}/instances:
get:
operationId: ListScaleSetInstances
parameters:
- description: Runner scale set ID.
in: path
name: scalesetID
required: true
type: string
responses:
"200":
description: Instances
schema:
$ref: '#/definitions/Instances'
default:
description: APIErrorResponse
schema:
$ref: '#/definitions/APIErrorResponse'
summary: List runner instances in a scale set.
tags:
- instances
produces:
- application/json
security:

View file

@ -1,3 +1,16 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package auth
import "net/http"

View file

@ -16,18 +16,19 @@ package auth
import (
"context"
"errors"
"fmt"
"time"
jwt "github.com/golang-jwt/jwt/v5"
"github.com/nbutton23/zxcvbn-go"
"golang.org/x/crypto/bcrypt"
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm-provider-common/util"
"github.com/cloudbase/garm/config"
"github.com/cloudbase/garm/database/common"
"github.com/cloudbase/garm/params"
jwt "github.com/golang-jwt/jwt/v5"
"github.com/nbutton23/zxcvbn-go"
"github.com/pkg/errors"
"golang.org/x/crypto/bcrypt"
)
func NewAuthenticator(cfg config.JWTAuth, store common.Store) *Authenticator {
@ -49,27 +50,30 @@ func (a *Authenticator) IsInitialized() bool {
func (a *Authenticator) GetJWTToken(ctx context.Context) (string, error) {
tokenID, err := util.GetRandomString(16)
if err != nil {
return "", errors.Wrap(err, "generating random string")
return "", fmt.Errorf("error generating random string: %w", err)
}
expireToken := time.Now().Add(a.cfg.TimeToLive.Duration())
expires := &jwt.NumericDate{
Time: expireToken,
}
generation := PasswordGeneration(ctx)
claims := JWTClaims{
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: expires,
// nolint:golangci-lint,godox
// TODO: make this configurable
Issuer: "garm",
},
UserID: UserID(ctx),
TokenID: tokenID,
IsAdmin: IsAdmin(ctx),
FullName: FullName(ctx),
UserID: UserID(ctx),
TokenID: tokenID,
IsAdmin: IsAdmin(ctx),
FullName: FullName(ctx),
Generation: generation,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(a.cfg.Secret))
if err != nil {
return "", errors.Wrap(err, "fetching token string")
return "", fmt.Errorf("error fetching token string: %w", err)
}
return tokenString, nil
@ -78,15 +82,15 @@ func (a *Authenticator) GetJWTToken(ctx context.Context) (string, error) {
// GetJWTMetricsToken returns a JWT token that can be used to read metrics.
// This token is not tied to a user, no user is stored in the db.
func (a *Authenticator) GetJWTMetricsToken(ctx context.Context) (string, error) {
if !IsAdmin(ctx) {
return "", runnerErrors.ErrUnauthorized
}
tokenID, err := util.GetRandomString(16)
if err != nil {
return "", errors.Wrap(err, "generating random string")
return "", fmt.Errorf("error generating random string: %w", err)
}
// nolint:golangci-lint,godox
// TODO: currently this is the same TTL as the normal Token
// maybe we should make this configurable
// it's usually pretty nasty if the monitoring fails because the token expired
@ -97,6 +101,7 @@ func (a *Authenticator) GetJWTMetricsToken(ctx context.Context) (string, error)
claims := JWTClaims{
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: expires,
// nolint:golangci-lint,godox
// TODO: make this configurable
Issuer: "garm",
},
@ -107,7 +112,7 @@ func (a *Authenticator) GetJWTMetricsToken(ctx context.Context) (string, error)
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(a.cfg.Secret))
if err != nil {
return "", errors.Wrap(err, "fetching token string")
return "", fmt.Errorf("error fetching token string: %w", err)
}
return tokenString, nil
@ -117,7 +122,7 @@ func (a *Authenticator) InitController(ctx context.Context, param params.NewUser
_, err := a.store.ControllerInfo()
if err != nil {
if !errors.Is(err, runnerErrors.ErrNotFound) {
return params.User{}, errors.Wrap(err, "initializing controller")
return params.User{}, fmt.Errorf("error initializing controller: %w", err)
}
}
if a.store.HasAdminUser(ctx) {
@ -147,7 +152,7 @@ func (a *Authenticator) InitController(ctx context.Context, param params.NewUser
hashed, err := util.PaswsordToBcrypt(param.Password)
if err != nil {
return params.User{}, errors.Wrap(err, "creating user")
return params.User{}, fmt.Errorf("error creating user: %w", err)
}
param.Password = hashed
@ -165,7 +170,7 @@ func (a *Authenticator) AuthenticateUser(ctx context.Context, info params.Passwo
if errors.Is(err, runnerErrors.ErrNotFound) {
return ctx, runnerErrors.ErrUnauthorized
}
return ctx, errors.Wrap(err, "authenticating")
return ctx, fmt.Errorf("error authenticating: %w", err)
}
if !user.Enabled {
@ -180,5 +185,5 @@ func (a *Authenticator) AuthenticateUser(ctx context.Context, info params.Passwo
return ctx, runnerErrors.ErrUnauthorized
}
return PopulateContext(ctx, user), nil
return PopulateContext(ctx, user, nil), nil
}

View file

@ -16,6 +16,7 @@ package auth
import (
"context"
"time"
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
@ -28,9 +29,11 @@ const (
fullNameKey contextFlags = "full_name"
readMetricsKey contextFlags = "read_metrics"
// UserIDFlag is the User ID flag we set in the context
UserIDFlag contextFlags = "user_id"
isEnabledFlag contextFlags = "is_enabled"
jwtTokenFlag contextFlags = "jwt_token"
UserIDFlag contextFlags = "user_id"
isEnabledFlag contextFlags = "is_enabled"
jwtTokenFlag contextFlags = "jwt_token"
authExpiresFlag contextFlags = "auth_expires"
passwordGenerationFlag contextFlags = "password_generation"
instanceIDKey contextFlags = "id"
instanceNameKey contextFlags = "name"
@ -41,8 +44,21 @@ const (
instanceTokenFetched contextFlags = "tokenFetched"
instanceHasJITConfig contextFlags = "hasJITConfig"
instanceParams contextFlags = "instanceParams"
instanceForgeTypeKey contextFlags = "forge_type"
)
func SetInstanceForgeType(ctx context.Context, val string) context.Context {
return context.WithValue(ctx, instanceForgeTypeKey, val)
}
func InstanceForgeType(ctx context.Context) params.EndpointType {
elem := ctx.Value(instanceForgeTypeKey)
if elem == nil {
return ""
}
return elem.(params.EndpointType)
}
func SetInstanceID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, instanceIDKey, id)
}
@ -156,7 +172,7 @@ func InstanceEntity(ctx context.Context) string {
return elem.(string)
}
func PopulateInstanceContext(ctx context.Context, instance params.Instance) context.Context {
func PopulateInstanceContext(ctx context.Context, instance params.Instance, claims *InstanceJWTClaims) context.Context {
ctx = SetInstanceID(ctx, instance.ID)
ctx = SetInstanceName(ctx, instance.Name)
ctx = SetInstancePoolID(ctx, instance.PoolID)
@ -164,19 +180,49 @@ func PopulateInstanceContext(ctx context.Context, instance params.Instance) cont
ctx = SetInstanceTokenFetched(ctx, instance.TokenFetched)
ctx = SetInstanceHasJITConfig(ctx, instance.JitConfiguration)
ctx = SetInstanceParams(ctx, instance)
ctx = SetInstanceForgeType(ctx, claims.ForgeType)
return ctx
}
// PopulateContext sets the appropriate fields in the context, based on
// the user object
func PopulateContext(ctx context.Context, user params.User) context.Context {
func PopulateContext(ctx context.Context, user params.User, authExpires *time.Time) context.Context {
ctx = SetUserID(ctx, user.ID)
ctx = SetAdmin(ctx, user.IsAdmin)
ctx = SetIsEnabled(ctx, user.Enabled)
ctx = SetFullName(ctx, user.FullName)
ctx = SetExpires(ctx, authExpires)
ctx = SetPasswordGeneration(ctx, user.Generation)
return ctx
}
func SetExpires(ctx context.Context, expires *time.Time) context.Context {
if expires == nil {
return ctx
}
return context.WithValue(ctx, authExpiresFlag, expires)
}
func Expires(ctx context.Context) *time.Time {
elem := ctx.Value(authExpiresFlag)
if elem == nil {
return nil
}
return elem.(*time.Time)
}
func SetPasswordGeneration(ctx context.Context, val uint) context.Context {
return context.WithValue(ctx, passwordGenerationFlag, val)
}
func PasswordGeneration(ctx context.Context) uint {
elem := ctx.Value(passwordGenerationFlag)
if elem == nil {
return 0
}
return elem.(uint)
}
// SetFullName sets the user full name in the context
func SetFullName(ctx context.Context, fullName string) context.Context {
return context.WithValue(ctx, fullNameKey, fullName)
@ -238,8 +284,10 @@ func UserID(ctx context.Context) string {
// GetAdminContext will return an admin context. This can be used internally
// when fetching users.
func GetAdminContext() context.Context {
ctx := context.Background()
func GetAdminContext(ctx context.Context) context.Context {
if ctx == nil {
ctx = context.Background()
}
ctx = SetUserID(ctx, "")
ctx = SetAdmin(ctx, true)
ctx = SetIsEnabled(ctx, true)

View file

@ -16,7 +16,7 @@ package auth
import (
"encoding/json"
"log"
"log/slog"
"net/http"
"github.com/cloudbase/garm/apiserver/params"
@ -37,16 +37,44 @@ type initRequired struct {
// Middleware implements the middleware interface
func (i *initRequired) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctrlInfo, err := i.store.ControllerInfo()
if err != nil || ctrlInfo.ControllerID.String() == "" {
ctx := r.Context()
if !i.store.HasAdminUser(ctx) {
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusConflict)
if err := json.NewEncoder(w).Encode(params.InitializationRequired); err != nil {
log.Printf("failed to encode response: %s", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
ctx := r.Context()
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func NewUrlsRequiredMiddleware(store common.Store) (Middleware, error) {
return &urlsRequired{
store: store,
}, nil
}
type urlsRequired struct {
store common.Store
}
func (u *urlsRequired) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctrlInfo, err := u.store.ControllerInfo()
if err != nil || ctrlInfo.MetadataURL == "" || ctrlInfo.CallbackURL == "" {
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusConflict)
if err := json.NewEncoder(w).Encode(params.URLsRequired); err != nil {
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
return
}
next.ServeHTTP(w, r.WithContext(ctx))
})
}

View file

@ -17,18 +17,20 @@ package auth
import (
"context"
"fmt"
"log/slog"
"math"
"net/http"
"strings"
"time"
jwt "github.com/golang-jwt/jwt/v5"
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
commonParams "github.com/cloudbase/garm-provider-common/params"
"github.com/cloudbase/garm/config"
dbCommon "github.com/cloudbase/garm/database/common"
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common"
jwt "github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
)
// InstanceJWTClaims holds JWT claims
@ -37,17 +39,38 @@ type InstanceJWTClaims struct {
Name string `json:"name"`
PoolID string `json:"provider_id"`
// Scope is either repository or organization
Scope params.PoolType `json:"scope"`
Scope params.ForgeEntityType `json:"scope"`
// Entity is the repo or org name
Entity string `json:"entity"`
Entity string `json:"entity"`
CreateAttempt int `json:"create_attempt"`
ForgeType string `json:"forge_type"`
jwt.RegisteredClaims
}
func NewInstanceJWTToken(instance params.Instance, secret, entity string, poolType params.PoolType, ttlMinutes uint) (string, error) {
func NewInstanceTokenGetter(jwtSecret string) (InstanceTokenGetter, error) {
if jwtSecret == "" {
return nil, fmt.Errorf("jwt secret is required")
}
return &instanceToken{
jwtSecret: jwtSecret,
}, nil
}
type instanceToken struct {
jwtSecret string
}
func (i *instanceToken) NewInstanceJWTToken(instance params.Instance, entity params.ForgeEntity, entityType params.ForgeEntityType, ttlMinutes uint) (string, error) {
// Token expiration is equal to the bootstrap timeout set on the pool plus the polling
// interval garm uses to check for timed out runners. Runners that have not sent their info
// by the end of this interval are most likely failed and will be reaped by garm anyway.
expireToken := time.Now().Add(time.Duration(ttlMinutes)*time.Minute + common.PoolReapTimeoutInterval)
var ttl int
if ttlMinutes > math.MaxInt {
ttl = math.MaxInt
} else {
ttl = int(ttlMinutes)
}
expireToken := time.Now().Add(time.Duration(ttl)*time.Minute + common.PoolReapTimeoutInterval)
expires := &jwt.NumericDate{
Time: expireToken,
}
@ -56,16 +79,18 @@ func NewInstanceJWTToken(instance params.Instance, secret, entity string, poolTy
ExpiresAt: expires,
Issuer: "garm",
},
ID: instance.ID,
Name: instance.Name,
PoolID: instance.PoolID,
Scope: poolType,
Entity: entity,
ID: instance.ID,
Name: instance.Name,
PoolID: instance.PoolID,
Scope: entityType,
Entity: entity.String(),
ForgeType: string(entity.Credentials.ForgeType),
CreateAttempt: instance.CreateAttempt,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(secret))
tokenString, err := token.SignedString([]byte(i.jwtSecret))
if err != nil {
return "", errors.Wrap(err, "signing token")
return "", fmt.Errorf("error signing token: %w", err)
}
return tokenString, nil
@ -95,29 +120,30 @@ func (amw *instanceMiddleware) claimsToContext(ctx context.Context, claims *Inst
return nil, runnerErrors.ErrUnauthorized
}
instanceInfo, err := amw.store.GetInstanceByName(ctx, claims.Name)
instanceInfo, err := amw.store.GetInstance(ctx, claims.Name)
if err != nil {
return ctx, runnerErrors.ErrUnauthorized
}
ctx = PopulateInstanceContext(ctx, instanceInfo)
ctx = PopulateInstanceContext(ctx, instanceInfo, claims)
return ctx, nil
}
// Middleware implements the middleware interface
func (amw *instanceMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// nolint:golangci-lint,godox
// TODO: Log error details when authentication fails
ctx := r.Context()
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) != 2 {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
@ -128,32 +154,61 @@ func (amw *instanceMiddleware) Middleware(next http.Handler) http.Handler {
}
return []byte(amw.cfg.Secret), nil
})
if err != nil {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
if !token.Valid {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
ctx, err = amw.claimsToContext(ctx, claims)
if err != nil {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
if InstanceID(ctx) == "" {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
runnerStatus := InstanceRunnerStatus(ctx)
if runnerStatus != params.RunnerInstalling && runnerStatus != params.RunnerPending {
// Instances that have finished installing can no longer authenticate to the API
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
instanceParams, err := InstanceParams(ctx)
if err != nil {
slog.InfoContext(
ctx, "could not find instance params",
"runner_name", InstanceName(ctx))
invalidAuthResponse(ctx, w)
return
}
// Token was generated for a previous attempt at creating this instance.
if claims.CreateAttempt != instanceParams.CreateAttempt {
slog.InfoContext(
ctx, "invalid token create attempt",
"runner_name", InstanceName(ctx),
"token_create_attempt", claims.CreateAttempt,
"instance_create_attempt", instanceParams.CreateAttempt)
invalidAuthResponse(ctx, w)
return
}
// Only allow instances that are in the creating or running state to authenticate.
if instanceParams.Status != commonParams.InstanceCreating && instanceParams.Status != commonParams.InstanceRunning {
slog.InfoContext(
ctx, "invalid instance status",
"runner_name", InstanceName(ctx),
"status", instanceParams.Status)
invalidAuthResponse(ctx, w)
return
}

View file

@ -14,9 +14,17 @@
package auth
import "net/http"
import (
"net/http"
"github.com/cloudbase/garm/params"
)
// Middleware defines an authentication middleware
type Middleware interface {
Middleware(next http.Handler) http.Handler
}
type InstanceTokenGetter interface {
NewInstanceJWTToken(instance params.Instance, entity params.ForgeEntity, poolType params.ForgeEntityType, ttlMinutes uint) (string, error)
}

View file

@ -18,16 +18,17 @@ import (
"context"
"encoding/json"
"fmt"
"log"
"log/slog"
"net/http"
"strings"
"time"
jwt "github.com/golang-jwt/jwt/v5"
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
apiParams "github.com/cloudbase/garm/apiserver/params"
"github.com/cloudbase/garm/config"
dbCommon "github.com/cloudbase/garm/database/common"
jwt "github.com/golang-jwt/jwt/v5"
)
// JWTClaims holds JWT claims
@ -37,6 +38,7 @@ type JWTClaims struct {
FullName string `json:"full_name"`
IsAdmin bool `json:"is_admin"`
ReadMetrics bool `json:"read_metrics"`
Generation uint `json:"generation"`
jwt.RegisteredClaims
}
@ -69,63 +71,85 @@ func (amw *jwtMiddleware) claimsToContext(ctx context.Context, claims *JWTClaims
return ctx, runnerErrors.ErrUnauthorized
}
ctx = PopulateContext(ctx, userInfo)
var expiresAt *time.Time
if claims.ExpiresAt != nil {
expires := claims.ExpiresAt.Time.UTC()
expiresAt = &expires
}
if userInfo.Generation != claims.Generation {
// Password was reset since token was issued. Invalidate.
return ctx, runnerErrors.ErrUnauthorized
}
ctx = PopulateContext(ctx, userInfo, expiresAt)
return ctx, nil
}
func invalidAuthResponse(w http.ResponseWriter) {
func invalidAuthResponse(ctx context.Context, w http.ResponseWriter) {
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusUnauthorized)
if err := json.NewEncoder(w).Encode(
apiParams.APIErrorResponse{
Error: "Authentication failed",
}); err != nil {
log.Printf("failed to encode response: %s", err)
slog.With(slog.Any("error", err)).ErrorContext(ctx, "failed to encode response")
}
}
func (amw *jwtMiddleware) getTokenFromRequest(r *http.Request) (string, error) {
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
cookie, err := r.Cookie("garm_token")
if err != nil {
return "", fmt.Errorf("failed to get cookie: %w", err)
}
return cookie.Value, nil
}
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) != 2 {
return "", fmt.Errorf("invalid auth header")
}
return bearerToken[1], nil
}
// Middleware implements the middleware interface
func (amw *jwtMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// nolint:golangci-lint,godox
// TODO: Log error details when authentication fails
ctx := r.Context()
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
invalidAuthResponse(w)
authToken, err := amw.getTokenFromRequest(r)
if err != nil {
slog.ErrorContext(ctx, "failed to get auth token", "error", err)
invalidAuthResponse(ctx, w)
return
}
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) != 2 {
invalidAuthResponse(w)
return
}
claims := &JWTClaims{}
token, err := jwt.ParseWithClaims(bearerToken[1], claims, func(token *jwt.Token) (interface{}, error) {
token, err := jwt.ParseWithClaims(authToken, claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("invalid signing method")
}
return []byte(amw.cfg.Secret), nil
})
if err != nil {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
if !token.Valid {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
ctx, err = amw.claimsToContext(ctx, claims)
if err != nil {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
if !IsEnabled(ctx) {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}

View file

@ -1,3 +1,16 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package auth
import (
@ -6,9 +19,9 @@ import (
"net/http"
"strings"
"github.com/cloudbase/garm/config"
jwt "github.com/golang-jwt/jwt/v5"
"github.com/cloudbase/garm/config"
)
type MetricsMiddleware struct {
@ -23,17 +36,16 @@ func NewMetricsMiddleware(cfg config.JWTAuth) (*MetricsMiddleware, error) {
func (m *MetricsMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
authorizationHeader := r.Header.Get("authorization")
if authorizationHeader == "" {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
bearerToken := strings.Split(authorizationHeader, " ")
if len(bearerToken) != 2 {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
@ -44,20 +56,19 @@ func (m *MetricsMiddleware) Middleware(next http.Handler) http.Handler {
}
return []byte(m.cfg.Secret), nil
})
if err != nil {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
if !token.Valid {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}
// we fully trust the claims
if !claims.ReadMetrics {
invalidAuthResponse(w)
invalidAuthResponse(ctx, w)
return
}

16
build-webapp.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
set -e
echo "Building GARM SPA (SvelteKit)..."
# Navigate to webapp directory
cd webapp
# Install dependencies if node_modules doesn't exist
npm install
# Build the SPA
echo "Building SPA..."
npm run build
echo "SPA built successfully!"

1040
cache/cache_test.go vendored Normal file

File diff suppressed because it is too large Load diff

148
cache/credentials_cache.go vendored Normal file
View file

@ -0,0 +1,148 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"sync"
"github.com/cloudbase/garm/params"
)
var (
credentialsCache *CredentialCache
giteaCredentialsCache *CredentialCache
)
func init() {
ghCredentialsCache := &CredentialCache{
cache: make(map[uint]params.ForgeCredentials),
}
gtCredentialsCache := &CredentialCache{
cache: make(map[uint]params.ForgeCredentials),
}
credentialsCache = ghCredentialsCache
giteaCredentialsCache = gtCredentialsCache
}
type CredentialCache struct {
mux sync.Mutex
cache map[uint]params.ForgeCredentials
}
func (g *CredentialCache) SetCredentialsRateLimit(credsID uint, rateLimit params.GithubRateLimit) {
g.mux.Lock()
defer g.mux.Unlock()
if creds, ok := g.cache[credsID]; ok {
creds.RateLimit = &rateLimit
g.cache[credsID] = creds
}
}
func (g *CredentialCache) SetCredentials(credentials params.ForgeCredentials) {
g.mux.Lock()
defer g.mux.Unlock()
g.cache[credentials.ID] = credentials
UpdateCredentialsInAffectedEntities(credentials)
}
func (g *CredentialCache) GetCredentials(id uint) (params.ForgeCredentials, bool) {
g.mux.Lock()
defer g.mux.Unlock()
if creds, ok := g.cache[id]; ok {
return creds, true
}
return params.ForgeCredentials{}, false
}
func (g *CredentialCache) DeleteCredentials(id uint) {
g.mux.Lock()
defer g.mux.Unlock()
delete(g.cache, id)
}
func (g *CredentialCache) GetAllCredentials() []params.ForgeCredentials {
g.mux.Lock()
defer g.mux.Unlock()
creds := make([]params.ForgeCredentials, 0, len(g.cache))
for _, cred := range g.cache {
creds = append(creds, cred)
}
// Sort the credentials by ID
sortByID(creds)
return creds
}
func (g *CredentialCache) GetAllCredentialsAsMap() map[uint]params.ForgeCredentials {
g.mux.Lock()
defer g.mux.Unlock()
creds := make(map[uint]params.ForgeCredentials, len(g.cache))
for id, cred := range g.cache {
creds[id] = cred
}
return creds
}
func SetGithubCredentials(credentials params.ForgeCredentials) {
credentialsCache.SetCredentials(credentials)
}
func GetGithubCredentials(id uint) (params.ForgeCredentials, bool) {
return credentialsCache.GetCredentials(id)
}
func DeleteGithubCredentials(id uint) {
credentialsCache.DeleteCredentials(id)
}
func GetAllGithubCredentials() []params.ForgeCredentials {
return credentialsCache.GetAllCredentials()
}
func SetCredentialsRateLimit(credsID uint, rateLimit params.GithubRateLimit) {
credentialsCache.SetCredentialsRateLimit(credsID, rateLimit)
}
func GetAllGithubCredentialsAsMap() map[uint]params.ForgeCredentials {
return credentialsCache.GetAllCredentialsAsMap()
}
func SetGiteaCredentials(credentials params.ForgeCredentials) {
giteaCredentialsCache.SetCredentials(credentials)
}
func GetGiteaCredentials(id uint) (params.ForgeCredentials, bool) {
return giteaCredentialsCache.GetCredentials(id)
}
func DeleteGiteaCredentials(id uint) {
giteaCredentialsCache.DeleteCredentials(id)
}
func GetAllGiteaCredentials() []params.ForgeCredentials {
return giteaCredentialsCache.GetAllCredentials()
}
func GetAllGiteaCredentialsAsMap() map[uint]params.ForgeCredentials {
return giteaCredentialsCache.GetAllCredentialsAsMap()
}

435
cache/entity_cache.go vendored Normal file
View file

@ -0,0 +1,435 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"sync"
"time"
"github.com/cloudbase/garm/params"
)
var entityCache *EntityCache
func init() {
ghEntityCache := &EntityCache{
entities: make(map[string]EntityItem),
}
entityCache = ghEntityCache
}
type RunnerGroupEntry struct {
RunnerGroupID int64
time time.Time
}
type EntityItem struct {
Entity params.ForgeEntity
Pools map[string]params.Pool
ScaleSets map[uint]params.ScaleSet
RunnerGroups map[string]RunnerGroupEntry
}
type EntityCache struct {
mux sync.Mutex
// entity IDs are UUID4s. It is highly unlikely they will collide (🤞).
entities map[string]EntityItem
}
func (e *EntityCache) UpdateCredentialsInAffectedEntities(creds params.ForgeCredentials) {
e.mux.Lock()
defer e.mux.Unlock()
for entityID, cache := range e.entities {
if cache.Entity.Credentials.GetID() == creds.GetID() {
cache.Entity.Credentials = creds
e.entities[entityID] = cache
}
}
}
func (e *EntityCache) GetEntity(entityID string) (params.ForgeEntity, bool) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
var creds params.ForgeCredentials
var ok bool
switch cache.Entity.Credentials.ForgeType {
case params.GithubEndpointType:
creds, ok = GetGithubCredentials(cache.Entity.Credentials.ID)
case params.GiteaEndpointType:
creds, ok = GetGiteaCredentials(cache.Entity.Credentials.ID)
}
if ok {
cache.Entity.Credentials = creds
}
return cache.Entity, true
}
return params.ForgeEntity{}, false
}
func (e *EntityCache) SetEntity(entity params.ForgeEntity) {
e.mux.Lock()
defer e.mux.Unlock()
cache, ok := e.entities[entity.ID]
if !ok {
e.entities[entity.ID] = EntityItem{
Entity: entity,
Pools: make(map[string]params.Pool),
ScaleSets: make(map[uint]params.ScaleSet),
RunnerGroups: make(map[string]RunnerGroupEntry),
}
return
}
cache.Entity = entity
e.entities[entity.ID] = cache
}
func (e *EntityCache) ReplaceEntityPools(entityID string, pools []params.Pool) {
e.mux.Lock()
defer e.mux.Unlock()
cache, ok := e.entities[entityID]
if !ok {
return
}
poolsByID := map[string]params.Pool{}
for _, pool := range pools {
poolsByID[pool.ID] = pool
}
cache.Pools = poolsByID
e.entities[entityID] = cache
}
func (e *EntityCache) ReplaceEntityScaleSets(entityID string, scaleSets []params.ScaleSet) {
e.mux.Lock()
defer e.mux.Unlock()
cache, ok := e.entities[entityID]
if !ok {
return
}
scaleSetsByID := map[uint]params.ScaleSet{}
for _, scaleSet := range scaleSets {
scaleSetsByID[scaleSet.ID] = scaleSet
}
cache.ScaleSets = scaleSetsByID
e.entities[entityID] = cache
}
func (e *EntityCache) DeleteEntity(entityID string) {
e.mux.Lock()
defer e.mux.Unlock()
delete(e.entities, entityID)
}
func (e *EntityCache) SetEntityPool(entityID string, pool params.Pool) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
cache.Pools[pool.ID] = pool
e.entities[entityID] = cache
}
}
func (e *EntityCache) SetEntityScaleSet(entityID string, scaleSet params.ScaleSet) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
cache.ScaleSets[scaleSet.ID] = scaleSet
e.entities[entityID] = cache
}
}
func (e *EntityCache) DeleteEntityPool(entityID string, poolID string) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
delete(cache.Pools, poolID)
e.entities[entityID] = cache
}
}
func (e *EntityCache) DeleteEntityScaleSet(entityID string, scaleSetID uint) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
delete(cache.ScaleSets, scaleSetID)
e.entities[entityID] = cache
}
}
func (e *EntityCache) GetEntityPool(entityID string, poolID string) (params.Pool, bool) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
if pool, ok := cache.Pools[poolID]; ok {
return pool, true
}
}
return params.Pool{}, false
}
func (e *EntityCache) GetEntityScaleSet(entityID string, scaleSetID uint) (params.ScaleSet, bool) {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
if scaleSet, ok := cache.ScaleSets[scaleSetID]; ok {
return scaleSet, true
}
}
return params.ScaleSet{}, false
}
func (e *EntityCache) FindPoolsMatchingAllTags(entityID string, tags []string) []params.Pool {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
var pools []params.Pool
for _, pool := range cache.Pools {
if pool.HasRequiredLabels(tags) {
pools = append(pools, pool)
}
}
// Sort the pools by creation date.
sortByCreationDate(pools)
return pools
}
return nil
}
func (e *EntityCache) GetEntityPools(entityID string) []params.Pool {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
var pools []params.Pool
for _, pool := range cache.Pools {
pools = append(pools, pool)
}
// Sort the pools by creation date.
sortByCreationDate(pools)
return pools
}
return nil
}
func (e *EntityCache) GetEntityScaleSets(entityID string) []params.ScaleSet {
e.mux.Lock()
defer e.mux.Unlock()
if cache, ok := e.entities[entityID]; ok {
var scaleSets []params.ScaleSet
for _, scaleSet := range cache.ScaleSets {
scaleSets = append(scaleSets, scaleSet)
}
// Sort the scale sets by creation date.
sortByID(scaleSets)
return scaleSets
}
return nil
}
func (e *EntityCache) GetEntitiesUsingCredentials(creds params.ForgeCredentials) []params.ForgeEntity {
e.mux.Lock()
defer e.mux.Unlock()
var entities []params.ForgeEntity
for _, cache := range e.entities {
if cache.Entity.Credentials.ForgeType != creds.ForgeType {
continue
}
if cache.Entity.Credentials.GetID() == creds.GetID() {
entities = append(entities, cache.Entity)
}
}
sortByCreationDate(entities)
return entities
}
func (e *EntityCache) GetAllEntities() []params.ForgeEntity {
e.mux.Lock()
defer e.mux.Unlock()
var entities []params.ForgeEntity
for _, cache := range e.entities {
// Get the credentials from the credentials cache.
var creds params.ForgeCredentials
var ok bool
switch cache.Entity.Credentials.ForgeType {
case params.GithubEndpointType:
creds, ok = GetGithubCredentials(cache.Entity.Credentials.ID)
case params.GiteaEndpointType:
creds, ok = GetGiteaCredentials(cache.Entity.Credentials.ID)
}
if ok {
cache.Entity.Credentials = creds
}
entities = append(entities, cache.Entity)
}
sortByCreationDate(entities)
return entities
}
func (e *EntityCache) GetAllPools() []params.Pool {
e.mux.Lock()
defer e.mux.Unlock()
var pools []params.Pool
for _, cache := range e.entities {
for _, pool := range cache.Pools {
pools = append(pools, pool)
}
}
sortByCreationDate(pools)
return pools
}
func (e *EntityCache) GetAllScaleSets() []params.ScaleSet {
e.mux.Lock()
defer e.mux.Unlock()
var scaleSets []params.ScaleSet
for _, cache := range e.entities {
for _, scaleSet := range cache.ScaleSets {
scaleSets = append(scaleSets, scaleSet)
}
}
sortByID(scaleSets)
return scaleSets
}
func (e *EntityCache) SetEntityRunnerGroup(entityID, runnerGroupName string, runnerGroupID int64) {
e.mux.Lock()
defer e.mux.Unlock()
if _, ok := e.entities[entityID]; ok {
e.entities[entityID].RunnerGroups[runnerGroupName] = RunnerGroupEntry{
RunnerGroupID: runnerGroupID,
time: time.Now().UTC(),
}
}
}
func (e *EntityCache) GetEntityRunnerGroup(entityID, runnerGroupName string) (int64, bool) {
e.mux.Lock()
defer e.mux.Unlock()
if _, ok := e.entities[entityID]; ok {
if runnerGroup, ok := e.entities[entityID].RunnerGroups[runnerGroupName]; ok {
if time.Now().UTC().After(runnerGroup.time.Add(1 * time.Hour)) {
delete(e.entities[entityID].RunnerGroups, runnerGroupName)
return 0, false
}
return runnerGroup.RunnerGroupID, true
}
}
return 0, false
}
func SetEntityRunnerGroup(entityID, runnerGroupName string, runnerGroupID int64) {
entityCache.SetEntityRunnerGroup(entityID, runnerGroupName, runnerGroupID)
}
func GetEntityRunnerGroup(entityID, runnerGroupName string) (int64, bool) {
return entityCache.GetEntityRunnerGroup(entityID, runnerGroupName)
}
func GetEntity(entityID string) (params.ForgeEntity, bool) {
return entityCache.GetEntity(entityID)
}
func SetEntity(entity params.ForgeEntity) {
entityCache.SetEntity(entity)
}
func ReplaceEntityPools(entityID string, pools []params.Pool) {
entityCache.ReplaceEntityPools(entityID, pools)
}
func ReplaceEntityScaleSets(entityID string, scaleSets []params.ScaleSet) {
entityCache.ReplaceEntityScaleSets(entityID, scaleSets)
}
func DeleteEntity(entityID string) {
entityCache.DeleteEntity(entityID)
}
func SetEntityPool(entityID string, pool params.Pool) {
entityCache.SetEntityPool(entityID, pool)
}
func SetEntityScaleSet(entityID string, scaleSet params.ScaleSet) {
entityCache.SetEntityScaleSet(entityID, scaleSet)
}
func DeleteEntityPool(entityID string, poolID string) {
entityCache.DeleteEntityPool(entityID, poolID)
}
func DeleteEntityScaleSet(entityID string, scaleSetID uint) {
entityCache.DeleteEntityScaleSet(entityID, scaleSetID)
}
func GetEntityPool(entityID string, poolID string) (params.Pool, bool) {
return entityCache.GetEntityPool(entityID, poolID)
}
func GetEntityScaleSet(entityID string, scaleSetID uint) (params.ScaleSet, bool) {
return entityCache.GetEntityScaleSet(entityID, scaleSetID)
}
func FindPoolsMatchingAllTags(entityID string, tags []string) []params.Pool {
return entityCache.FindPoolsMatchingAllTags(entityID, tags)
}
func GetEntityPools(entityID string) []params.Pool {
return entityCache.GetEntityPools(entityID)
}
func GetEntityScaleSets(entityID string) []params.ScaleSet {
return entityCache.GetEntityScaleSets(entityID)
}
func UpdateCredentialsInAffectedEntities(creds params.ForgeCredentials) {
entityCache.UpdateCredentialsInAffectedEntities(creds)
}
func GetEntitiesUsingCredentials(creds params.ForgeCredentials) []params.ForgeEntity {
return entityCache.GetEntitiesUsingCredentials(creds)
}
func GetAllEntities() []params.ForgeEntity {
return entityCache.GetAllEntities()
}
func GetAllPools() []params.Pool {
return entityCache.GetAllPools()
}
func GetAllScaleSets() []params.ScaleSet {
return entityCache.GetAllScaleSets()
}

60
cache/github_client.go vendored Normal file
View file

@ -0,0 +1,60 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"sync"
"github.com/cloudbase/garm/runner/common"
)
var ghClientCache *GithubClientCache
type GithubClientCache struct {
mux sync.Mutex
cache map[string]common.GithubClient
}
func init() {
clientCache := &GithubClientCache{
cache: make(map[string]common.GithubClient),
}
ghClientCache = clientCache
}
func (g *GithubClientCache) SetClient(entityID string, client common.GithubClient) {
g.mux.Lock()
defer g.mux.Unlock()
g.cache[entityID] = client
}
func (g *GithubClientCache) GetClient(entityID string) (common.GithubClient, bool) {
g.mux.Lock()
defer g.mux.Unlock()
if client, ok := g.cache[entityID]; ok {
return client, true
}
return nil, false
}
func SetGithubClient(entityID string, client common.GithubClient) {
ghClientCache.SetClient(entityID, client)
}
func GetGithubClient(entityID string) (common.GithubClient, bool) {
return ghClientCache.GetClient(entityID)
}

143
cache/instance_cache.go vendored Normal file
View file

@ -0,0 +1,143 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"sync"
"github.com/cloudbase/garm/params"
)
var instanceCache *InstanceCache
func init() {
cache := &InstanceCache{
cache: make(map[string]params.Instance),
}
instanceCache = cache
}
type InstanceCache struct {
mux sync.Mutex
cache map[string]params.Instance
}
func (i *InstanceCache) SetInstance(instance params.Instance) {
i.mux.Lock()
defer i.mux.Unlock()
i.cache[instance.Name] = instance
}
func (i *InstanceCache) GetInstance(name string) (params.Instance, bool) {
i.mux.Lock()
defer i.mux.Unlock()
if instance, ok := i.cache[name]; ok {
return instance, true
}
return params.Instance{}, false
}
func (i *InstanceCache) DeleteInstance(name string) {
i.mux.Lock()
defer i.mux.Unlock()
delete(i.cache, name)
}
func (i *InstanceCache) GetAllInstances() []params.Instance {
i.mux.Lock()
defer i.mux.Unlock()
instances := make([]params.Instance, 0, len(i.cache))
for _, instance := range i.cache {
instances = append(instances, instance)
}
sortByCreationDate(instances)
return instances
}
func (i *InstanceCache) GetInstancesForPool(poolID string) []params.Instance {
i.mux.Lock()
defer i.mux.Unlock()
var filteredInstances []params.Instance
for _, instance := range i.cache {
if instance.PoolID == poolID {
filteredInstances = append(filteredInstances, instance)
}
}
sortByCreationDate(filteredInstances)
return filteredInstances
}
func (i *InstanceCache) GetInstancesForScaleSet(scaleSetID uint) []params.Instance {
i.mux.Lock()
defer i.mux.Unlock()
var filteredInstances []params.Instance
for _, instance := range i.cache {
if instance.ScaleSetID == scaleSetID {
filteredInstances = append(filteredInstances, instance)
}
}
sortByCreationDate(filteredInstances)
return filteredInstances
}
func (i *InstanceCache) GetEntityInstances(entityID string) []params.Instance {
pools := GetEntityPools(entityID)
poolsAsMap := map[string]bool{}
for _, pool := range pools {
poolsAsMap[pool.ID] = true
}
ret := []params.Instance{}
for _, val := range i.GetAllInstances() {
if _, ok := poolsAsMap[val.PoolID]; ok {
ret = append(ret, val)
}
}
return ret
}
func SetInstanceCache(instance params.Instance) {
instanceCache.SetInstance(instance)
}
func GetInstanceCache(name string) (params.Instance, bool) {
return instanceCache.GetInstance(name)
}
func DeleteInstanceCache(name string) {
instanceCache.DeleteInstance(name)
}
func GetAllInstancesCache() []params.Instance {
return instanceCache.GetAllInstances()
}
func GetInstancesForPool(poolID string) []params.Instance {
return instanceCache.GetInstancesForPool(poolID)
}
func GetInstancesForScaleSet(scaleSetID uint) []params.Instance {
return instanceCache.GetInstancesForScaleSet(scaleSetID)
}
func GetEntityInstances(entityID string) []params.Instance {
return instanceCache.GetEntityInstances(entityID)
}

116
cache/tools_cache.go vendored Normal file
View file

@ -0,0 +1,116 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"fmt"
"sync"
"time"
commonParams "github.com/cloudbase/garm-provider-common/params"
"github.com/cloudbase/garm/params"
)
var githubToolsCache *GithubToolsCache
func init() {
ghToolsCache := &GithubToolsCache{
entities: make(map[string]GithubEntityTools),
}
githubToolsCache = ghToolsCache
}
type GithubEntityTools struct {
updatedAt time.Time
expiresAt time.Time
err error
entity params.ForgeEntity
tools []commonParams.RunnerApplicationDownload
}
type GithubToolsCache struct {
mux sync.Mutex
// entity IDs are UUID4s. It is highly unlikely they will collide (🤞).
entities map[string]GithubEntityTools
}
func (g *GithubToolsCache) Get(entityID string) ([]commonParams.RunnerApplicationDownload, error) {
g.mux.Lock()
defer g.mux.Unlock()
if cache, ok := g.entities[entityID]; ok {
if cache.entity.Credentials.ForgeType == params.GithubEndpointType {
if time.Now().UTC().After(cache.expiresAt.Add(-5 * time.Minute)) {
// Stale cache, remove it.
delete(g.entities, entityID)
return nil, fmt.Errorf("cache expired for entity %s", entityID)
}
}
if cache.err != nil {
return nil, cache.err
}
return cache.tools, nil
}
return nil, fmt.Errorf("no cache found for entity %s", entityID)
}
func (g *GithubToolsCache) Set(entity params.ForgeEntity, tools []commonParams.RunnerApplicationDownload) {
g.mux.Lock()
defer g.mux.Unlock()
forgeTools := GithubEntityTools{
updatedAt: time.Now(),
entity: entity,
tools: tools,
err: nil,
}
if entity.Credentials.ForgeType == params.GithubEndpointType {
forgeTools.expiresAt = time.Now().Add(1 * time.Hour)
}
g.entities[entity.ID] = forgeTools
}
func (g *GithubToolsCache) SetToolsError(entity params.ForgeEntity, err error) {
g.mux.Lock()
defer g.mux.Unlock()
// If the entity is not in the cache, add it with the error.
cache, ok := g.entities[entity.ID]
if !ok {
g.entities[entity.ID] = GithubEntityTools{
updatedAt: time.Now(),
entity: entity,
err: err,
}
return
}
// Update the error for the existing entity.
cache.err = err
g.entities[entity.ID] = cache
}
func SetGithubToolsCache(entity params.ForgeEntity, tools []commonParams.RunnerApplicationDownload) {
githubToolsCache.Set(entity, tools)
}
func GetGithubToolsCache(entityID string) ([]commonParams.RunnerApplicationDownload, error) {
return githubToolsCache.Get(entityID)
}
func SetGithubToolsCacheError(entity params.ForgeEntity, err error) {
githubToolsCache.SetToolsError(entity, err)
}

32
cache/util.go vendored Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2025 Cloudbase Solutions SRL
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package cache
import (
"sort"
"github.com/cloudbase/garm/params"
)
func sortByID[T params.IDGetter](s []T) {
sort.Slice(s, func(i, j int) bool {
return s[i].GetID() < s[j].GetID()
})
}
func sortByCreationDate[T params.CreationDateGetter](s []T) {
sort.Slice(s, func(i, j int) bool {
return s[i].GetCreatedAt().Before(s[j].GetCreatedAt())
})
}

View file

@ -0,0 +1,106 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// New creates a new controller API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService {
return &Client{transport: transport, formats: formats}
}
// New creates a new controller API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new controller API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client for controller API
*/
type Client struct {
transport runtime.ClientTransport
formats strfmt.Registry
}
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
type ClientService interface {
UpdateController(params *UpdateControllerParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateControllerOK, error)
SetTransport(transport runtime.ClientTransport)
}
/*
UpdateController updates controller
*/
func (a *Client) UpdateController(params *UpdateControllerParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateControllerOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewUpdateControllerParams()
}
op := &runtime.ClientOperation{
ID: "UpdateController",
Method: "PUT",
PathPattern: "/controller",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &UpdateControllerReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*UpdateControllerOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for UpdateController: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewUpdateControllerParams creates a new UpdateControllerParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewUpdateControllerParams() *UpdateControllerParams {
return &UpdateControllerParams{
timeout: cr.DefaultTimeout,
}
}
// NewUpdateControllerParamsWithTimeout creates a new UpdateControllerParams object
// with the ability to set a timeout on a request.
func NewUpdateControllerParamsWithTimeout(timeout time.Duration) *UpdateControllerParams {
return &UpdateControllerParams{
timeout: timeout,
}
}
// NewUpdateControllerParamsWithContext creates a new UpdateControllerParams object
// with the ability to set a context for a request.
func NewUpdateControllerParamsWithContext(ctx context.Context) *UpdateControllerParams {
return &UpdateControllerParams{
Context: ctx,
}
}
// NewUpdateControllerParamsWithHTTPClient creates a new UpdateControllerParams object
// with the ability to set a custom HTTPClient for a request.
func NewUpdateControllerParamsWithHTTPClient(client *http.Client) *UpdateControllerParams {
return &UpdateControllerParams{
HTTPClient: client,
}
}
/*
UpdateControllerParams contains all the parameters to send to the API endpoint
for the update controller operation.
Typically these are written to a http.Request.
*/
type UpdateControllerParams struct {
/* Body.
Parameters used when updating the controller.
*/
Body garm_params.UpdateControllerParams
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the update controller params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateControllerParams) WithDefaults() *UpdateControllerParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the update controller params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateControllerParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the update controller params
func (o *UpdateControllerParams) WithTimeout(timeout time.Duration) *UpdateControllerParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the update controller params
func (o *UpdateControllerParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the update controller params
func (o *UpdateControllerParams) WithContext(ctx context.Context) *UpdateControllerParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the update controller params
func (o *UpdateControllerParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the update controller params
func (o *UpdateControllerParams) WithHTTPClient(client *http.Client) *UpdateControllerParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the update controller params
func (o *UpdateControllerParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the update controller params
func (o *UpdateControllerParams) WithBody(body garm_params.UpdateControllerParams) *UpdateControllerParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the update controller params
func (o *UpdateControllerParams) SetBody(body garm_params.UpdateControllerParams) {
o.Body = body
}
// WriteToRequest writes these params to a swagger request
func (o *UpdateControllerParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package controller
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// UpdateControllerReader is a Reader for the UpdateController structure.
type UpdateControllerReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *UpdateControllerReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewUpdateControllerOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewUpdateControllerBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[PUT /controller] UpdateController", response, response.Code())
}
}
// NewUpdateControllerOK creates a UpdateControllerOK with default headers values
func NewUpdateControllerOK() *UpdateControllerOK {
return &UpdateControllerOK{}
}
/*
UpdateControllerOK describes a response with status code 200, with default header values.
ControllerInfo
*/
type UpdateControllerOK struct {
Payload garm_params.ControllerInfo
}
// IsSuccess returns true when this update controller o k response has a 2xx status code
func (o *UpdateControllerOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this update controller o k response has a 3xx status code
func (o *UpdateControllerOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this update controller o k response has a 4xx status code
func (o *UpdateControllerOK) IsClientError() bool {
return false
}
// IsServerError returns true when this update controller o k response has a 5xx status code
func (o *UpdateControllerOK) IsServerError() bool {
return false
}
// IsCode returns true when this update controller o k response a status code equal to that given
func (o *UpdateControllerOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the update controller o k response
func (o *UpdateControllerOK) Code() int {
return 200
}
func (o *UpdateControllerOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /controller][%d] updateControllerOK %s", 200, payload)
}
func (o *UpdateControllerOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /controller][%d] updateControllerOK %s", 200, payload)
}
func (o *UpdateControllerOK) GetPayload() garm_params.ControllerInfo {
return o.Payload
}
func (o *UpdateControllerOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewUpdateControllerBadRequest creates a UpdateControllerBadRequest with default headers values
func NewUpdateControllerBadRequest() *UpdateControllerBadRequest {
return &UpdateControllerBadRequest{}
}
/*
UpdateControllerBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type UpdateControllerBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this update controller bad request response has a 2xx status code
func (o *UpdateControllerBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this update controller bad request response has a 3xx status code
func (o *UpdateControllerBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this update controller bad request response has a 4xx status code
func (o *UpdateControllerBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this update controller bad request response has a 5xx status code
func (o *UpdateControllerBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this update controller bad request response a status code equal to that given
func (o *UpdateControllerBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the update controller bad request response
func (o *UpdateControllerBadRequest) Code() int {
return 400
}
func (o *UpdateControllerBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /controller][%d] updateControllerBadRequest %s", 400, payload)
}
func (o *UpdateControllerBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /controller][%d] updateControllerBadRequest %s", 400, payload)
}
func (o *UpdateControllerBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *UpdateControllerBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
@ -17,6 +18,31 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientServi
return &Client{transport: transport, formats: formats}
}
// New creates a new controller info API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new controller info API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client for controller info API
*/
@ -25,7 +51,7 @@ type Client struct {
formats strfmt.Registry
}
// ClientOption is the option for Client methods
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods

View file

@ -6,6 +6,7 @@ package controller_info
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -86,11 +87,13 @@ func (o *ControllerInfoOK) Code() int {
}
func (o *ControllerInfoOK) Error() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %s", 200, payload)
}
func (o *ControllerInfoOK) String() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoOK %s", 200, payload)
}
func (o *ControllerInfoOK) GetPayload() garm_params.ControllerInfo {
@ -152,11 +155,13 @@ func (o *ControllerInfoConflict) Code() int {
}
func (o *ControllerInfoConflict) Error() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %+v", 409, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %s", 409, payload)
}
func (o *ControllerInfoConflict) String() string {
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %+v", 409, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /controller-info][%d] controllerInfoConflict %s", 409, payload)
}
func (o *ControllerInfoConflict) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewCreateCredentialsParams creates a new CreateCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCreateCredentialsParams() *CreateCredentialsParams {
return &CreateCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewCreateCredentialsParamsWithTimeout creates a new CreateCredentialsParams object
// with the ability to set a timeout on a request.
func NewCreateCredentialsParamsWithTimeout(timeout time.Duration) *CreateCredentialsParams {
return &CreateCredentialsParams{
timeout: timeout,
}
}
// NewCreateCredentialsParamsWithContext creates a new CreateCredentialsParams object
// with the ability to set a context for a request.
func NewCreateCredentialsParamsWithContext(ctx context.Context) *CreateCredentialsParams {
return &CreateCredentialsParams{
Context: ctx,
}
}
// NewCreateCredentialsParamsWithHTTPClient creates a new CreateCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewCreateCredentialsParamsWithHTTPClient(client *http.Client) *CreateCredentialsParams {
return &CreateCredentialsParams{
HTTPClient: client,
}
}
/*
CreateCredentialsParams contains all the parameters to send to the API endpoint
for the create credentials operation.
Typically these are written to a http.Request.
*/
type CreateCredentialsParams struct {
/* Body.
Parameters used when creating a GitHub credential.
*/
Body garm_params.CreateGithubCredentialsParams
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the create credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateCredentialsParams) WithDefaults() *CreateCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the create credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the create credentials params
func (o *CreateCredentialsParams) WithTimeout(timeout time.Duration) *CreateCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the create credentials params
func (o *CreateCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the create credentials params
func (o *CreateCredentialsParams) WithContext(ctx context.Context) *CreateCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the create credentials params
func (o *CreateCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the create credentials params
func (o *CreateCredentialsParams) WithHTTPClient(client *http.Client) *CreateCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the create credentials params
func (o *CreateCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the create credentials params
func (o *CreateCredentialsParams) WithBody(body garm_params.CreateGithubCredentialsParams) *CreateCredentialsParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the create credentials params
func (o *CreateCredentialsParams) SetBody(body garm_params.CreateGithubCredentialsParams) {
o.Body = body
}
// WriteToRequest writes these params to a swagger request
func (o *CreateCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// CreateCredentialsReader is a Reader for the CreateCredentials structure.
type CreateCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *CreateCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewCreateCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewCreateCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[POST /github/credentials] CreateCredentials", response, response.Code())
}
}
// NewCreateCredentialsOK creates a CreateCredentialsOK with default headers values
func NewCreateCredentialsOK() *CreateCredentialsOK {
return &CreateCredentialsOK{}
}
/*
CreateCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type CreateCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this create credentials o k response has a 2xx status code
func (o *CreateCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this create credentials o k response has a 3xx status code
func (o *CreateCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this create credentials o k response has a 4xx status code
func (o *CreateCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this create credentials o k response has a 5xx status code
func (o *CreateCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this create credentials o k response a status code equal to that given
func (o *CreateCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the create credentials o k response
func (o *CreateCredentialsOK) Code() int {
return 200
}
func (o *CreateCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/credentials][%d] createCredentialsOK %s", 200, payload)
}
func (o *CreateCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/credentials][%d] createCredentialsOK %s", 200, payload)
}
func (o *CreateCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *CreateCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewCreateCredentialsBadRequest creates a CreateCredentialsBadRequest with default headers values
func NewCreateCredentialsBadRequest() *CreateCredentialsBadRequest {
return &CreateCredentialsBadRequest{}
}
/*
CreateCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type CreateCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this create credentials bad request response has a 2xx status code
func (o *CreateCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this create credentials bad request response has a 3xx status code
func (o *CreateCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this create credentials bad request response has a 4xx status code
func (o *CreateCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this create credentials bad request response has a 5xx status code
func (o *CreateCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this create credentials bad request response a status code equal to that given
func (o *CreateCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the create credentials bad request response
func (o *CreateCredentialsBadRequest) Code() int {
return 400
}
func (o *CreateCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/credentials][%d] createCredentialsBadRequest %s", 400, payload)
}
func (o *CreateCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/credentials][%d] createCredentialsBadRequest %s", 400, payload)
}
func (o *CreateCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *CreateCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewCreateGiteaCredentialsParams creates a new CreateGiteaCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCreateGiteaCredentialsParams() *CreateGiteaCredentialsParams {
return &CreateGiteaCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewCreateGiteaCredentialsParamsWithTimeout creates a new CreateGiteaCredentialsParams object
// with the ability to set a timeout on a request.
func NewCreateGiteaCredentialsParamsWithTimeout(timeout time.Duration) *CreateGiteaCredentialsParams {
return &CreateGiteaCredentialsParams{
timeout: timeout,
}
}
// NewCreateGiteaCredentialsParamsWithContext creates a new CreateGiteaCredentialsParams object
// with the ability to set a context for a request.
func NewCreateGiteaCredentialsParamsWithContext(ctx context.Context) *CreateGiteaCredentialsParams {
return &CreateGiteaCredentialsParams{
Context: ctx,
}
}
// NewCreateGiteaCredentialsParamsWithHTTPClient creates a new CreateGiteaCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewCreateGiteaCredentialsParamsWithHTTPClient(client *http.Client) *CreateGiteaCredentialsParams {
return &CreateGiteaCredentialsParams{
HTTPClient: client,
}
}
/*
CreateGiteaCredentialsParams contains all the parameters to send to the API endpoint
for the create gitea credentials operation.
Typically these are written to a http.Request.
*/
type CreateGiteaCredentialsParams struct {
/* Body.
Parameters used when creating a Gitea credential.
*/
Body garm_params.CreateGiteaCredentialsParams
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the create gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGiteaCredentialsParams) WithDefaults() *CreateGiteaCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the create gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGiteaCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) WithTimeout(timeout time.Duration) *CreateGiteaCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) WithContext(ctx context.Context) *CreateGiteaCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) WithHTTPClient(client *http.Client) *CreateGiteaCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) WithBody(body garm_params.CreateGiteaCredentialsParams) *CreateGiteaCredentialsParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the create gitea credentials params
func (o *CreateGiteaCredentialsParams) SetBody(body garm_params.CreateGiteaCredentialsParams) {
o.Body = body
}
// WriteToRequest writes these params to a swagger request
func (o *CreateGiteaCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// CreateGiteaCredentialsReader is a Reader for the CreateGiteaCredentials structure.
type CreateGiteaCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *CreateGiteaCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewCreateGiteaCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewCreateGiteaCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[POST /gitea/credentials] CreateGiteaCredentials", response, response.Code())
}
}
// NewCreateGiteaCredentialsOK creates a CreateGiteaCredentialsOK with default headers values
func NewCreateGiteaCredentialsOK() *CreateGiteaCredentialsOK {
return &CreateGiteaCredentialsOK{}
}
/*
CreateGiteaCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type CreateGiteaCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this create gitea credentials o k response has a 2xx status code
func (o *CreateGiteaCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this create gitea credentials o k response has a 3xx status code
func (o *CreateGiteaCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this create gitea credentials o k response has a 4xx status code
func (o *CreateGiteaCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this create gitea credentials o k response has a 5xx status code
func (o *CreateGiteaCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this create gitea credentials o k response a status code equal to that given
func (o *CreateGiteaCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the create gitea credentials o k response
func (o *CreateGiteaCredentialsOK) Code() int {
return 200
}
func (o *CreateGiteaCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/credentials][%d] createGiteaCredentialsOK %s", 200, payload)
}
func (o *CreateGiteaCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/credentials][%d] createGiteaCredentialsOK %s", 200, payload)
}
func (o *CreateGiteaCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *CreateGiteaCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewCreateGiteaCredentialsBadRequest creates a CreateGiteaCredentialsBadRequest with default headers values
func NewCreateGiteaCredentialsBadRequest() *CreateGiteaCredentialsBadRequest {
return &CreateGiteaCredentialsBadRequest{}
}
/*
CreateGiteaCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type CreateGiteaCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this create gitea credentials bad request response has a 2xx status code
func (o *CreateGiteaCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this create gitea credentials bad request response has a 3xx status code
func (o *CreateGiteaCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this create gitea credentials bad request response has a 4xx status code
func (o *CreateGiteaCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this create gitea credentials bad request response has a 5xx status code
func (o *CreateGiteaCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this create gitea credentials bad request response a status code equal to that given
func (o *CreateGiteaCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the create gitea credentials bad request response
func (o *CreateGiteaCredentialsBadRequest) Code() int {
return 400
}
func (o *CreateGiteaCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/credentials][%d] createGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *CreateGiteaCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/credentials][%d] createGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *CreateGiteaCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *CreateGiteaCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
@ -17,6 +18,31 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientServi
return &Client{transport: transport, formats: formats}
}
// New creates a new credentials API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new credentials API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client for credentials API
*/
@ -25,16 +51,254 @@ type Client struct {
formats strfmt.Registry
}
// ClientOption is the option for Client methods
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
type ClientService interface {
CreateCredentials(params *CreateCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateCredentialsOK, error)
CreateGiteaCredentials(params *CreateGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGiteaCredentialsOK, error)
DeleteCredentials(params *DeleteCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
DeleteGiteaCredentials(params *DeleteGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
GetCredentials(params *GetCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetCredentialsOK, error)
GetGiteaCredentials(params *GetGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGiteaCredentialsOK, error)
ListCredentials(params *ListCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListCredentialsOK, error)
ListGiteaCredentials(params *ListGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGiteaCredentialsOK, error)
UpdateCredentials(params *UpdateCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateCredentialsOK, error)
UpdateGiteaCredentials(params *UpdateGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGiteaCredentialsOK, error)
SetTransport(transport runtime.ClientTransport)
}
/*
CreateCredentials creates a git hub credential
*/
func (a *Client) CreateCredentials(params *CreateCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCreateCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "CreateCredentials",
Method: "POST",
PathPattern: "/github/credentials",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &CreateCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*CreateCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for CreateCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
CreateGiteaCredentials creates a gitea credential
*/
func (a *Client) CreateGiteaCredentials(params *CreateGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGiteaCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCreateGiteaCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "CreateGiteaCredentials",
Method: "POST",
PathPattern: "/gitea/credentials",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &CreateGiteaCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*CreateGiteaCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for CreateGiteaCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
DeleteCredentials deletes a git hub credential
*/
func (a *Client) DeleteCredentials(params *DeleteCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error {
// TODO: Validate the params before sending
if params == nil {
params = NewDeleteCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "DeleteCredentials",
Method: "DELETE",
PathPattern: "/github/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &DeleteCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
_, err := a.transport.Submit(op)
if err != nil {
return err
}
return nil
}
/*
DeleteGiteaCredentials deletes a gitea credential
*/
func (a *Client) DeleteGiteaCredentials(params *DeleteGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error {
// TODO: Validate the params before sending
if params == nil {
params = NewDeleteGiteaCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "DeleteGiteaCredentials",
Method: "DELETE",
PathPattern: "/gitea/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &DeleteGiteaCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
_, err := a.transport.Submit(op)
if err != nil {
return err
}
return nil
}
/*
GetCredentials gets a git hub credential
*/
func (a *Client) GetCredentials(params *GetCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "GetCredentials",
Method: "GET",
PathPattern: "/github/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &GetCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*GetCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for GetCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
GetGiteaCredentials gets a gitea credential
*/
func (a *Client) GetGiteaCredentials(params *GetGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGiteaCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetGiteaCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "GetGiteaCredentials",
Method: "GET",
PathPattern: "/gitea/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &GetGiteaCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*GetGiteaCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for GetGiteaCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
ListCredentials lists all credentials
*/
@ -46,7 +310,7 @@ func (a *Client) ListCredentials(params *ListCredentialsParams, authInfo runtime
op := &runtime.ClientOperation{
ID: "ListCredentials",
Method: "GET",
PathPattern: "/credentials",
PathPattern: "/github/credentials",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
@ -74,6 +338,123 @@ func (a *Client) ListCredentials(params *ListCredentialsParams, authInfo runtime
panic(msg)
}
/*
ListGiteaCredentials lists all credentials
*/
func (a *Client) ListGiteaCredentials(params *ListGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGiteaCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewListGiteaCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "ListGiteaCredentials",
Method: "GET",
PathPattern: "/gitea/credentials",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ListGiteaCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ListGiteaCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for ListGiteaCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
UpdateCredentials updates a git hub credential
*/
func (a *Client) UpdateCredentials(params *UpdateCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewUpdateCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "UpdateCredentials",
Method: "PUT",
PathPattern: "/github/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &UpdateCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*UpdateCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for UpdateCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
UpdateGiteaCredentials updates a gitea credential
*/
func (a *Client) UpdateGiteaCredentials(params *UpdateGiteaCredentialsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGiteaCredentialsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewUpdateGiteaCredentialsParams()
}
op := &runtime.ClientOperation{
ID: "UpdateGiteaCredentials",
Method: "PUT",
PathPattern: "/gitea/credentials/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &UpdateGiteaCredentialsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*UpdateGiteaCredentialsOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for UpdateGiteaCredentials: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport

View file

@ -0,0 +1,152 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewDeleteCredentialsParams creates a new DeleteCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewDeleteCredentialsParams() *DeleteCredentialsParams {
return &DeleteCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewDeleteCredentialsParamsWithTimeout creates a new DeleteCredentialsParams object
// with the ability to set a timeout on a request.
func NewDeleteCredentialsParamsWithTimeout(timeout time.Duration) *DeleteCredentialsParams {
return &DeleteCredentialsParams{
timeout: timeout,
}
}
// NewDeleteCredentialsParamsWithContext creates a new DeleteCredentialsParams object
// with the ability to set a context for a request.
func NewDeleteCredentialsParamsWithContext(ctx context.Context) *DeleteCredentialsParams {
return &DeleteCredentialsParams{
Context: ctx,
}
}
// NewDeleteCredentialsParamsWithHTTPClient creates a new DeleteCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewDeleteCredentialsParamsWithHTTPClient(client *http.Client) *DeleteCredentialsParams {
return &DeleteCredentialsParams{
HTTPClient: client,
}
}
/*
DeleteCredentialsParams contains all the parameters to send to the API endpoint
for the delete credentials operation.
Typically these are written to a http.Request.
*/
type DeleteCredentialsParams struct {
/* ID.
ID of the GitHub credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the delete credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteCredentialsParams) WithDefaults() *DeleteCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the delete credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the delete credentials params
func (o *DeleteCredentialsParams) WithTimeout(timeout time.Duration) *DeleteCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the delete credentials params
func (o *DeleteCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the delete credentials params
func (o *DeleteCredentialsParams) WithContext(ctx context.Context) *DeleteCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the delete credentials params
func (o *DeleteCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the delete credentials params
func (o *DeleteCredentialsParams) WithHTTPClient(client *http.Client) *DeleteCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the delete credentials params
func (o *DeleteCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the delete credentials params
func (o *DeleteCredentialsParams) WithID(id int64) *DeleteCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the delete credentials params
func (o *DeleteCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *DeleteCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,106 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
)
// DeleteCredentialsReader is a Reader for the DeleteCredentials structure.
type DeleteCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *DeleteCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
result := NewDeleteCredentialsDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
// NewDeleteCredentialsDefault creates a DeleteCredentialsDefault with default headers values
func NewDeleteCredentialsDefault(code int) *DeleteCredentialsDefault {
return &DeleteCredentialsDefault{
_statusCode: code,
}
}
/*
DeleteCredentialsDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type DeleteCredentialsDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this delete credentials default response has a 2xx status code
func (o *DeleteCredentialsDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this delete credentials default response has a 3xx status code
func (o *DeleteCredentialsDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this delete credentials default response has a 4xx status code
func (o *DeleteCredentialsDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this delete credentials default response has a 5xx status code
func (o *DeleteCredentialsDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this delete credentials default response a status code equal to that given
func (o *DeleteCredentialsDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the delete credentials default response
func (o *DeleteCredentialsDefault) Code() int {
return o._statusCode
}
func (o *DeleteCredentialsDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /github/credentials/{id}][%d] DeleteCredentials default %s", o._statusCode, payload)
}
func (o *DeleteCredentialsDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /github/credentials/{id}][%d] DeleteCredentials default %s", o._statusCode, payload)
}
func (o *DeleteCredentialsDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *DeleteCredentialsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,152 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewDeleteGiteaCredentialsParams creates a new DeleteGiteaCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewDeleteGiteaCredentialsParams() *DeleteGiteaCredentialsParams {
return &DeleteGiteaCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewDeleteGiteaCredentialsParamsWithTimeout creates a new DeleteGiteaCredentialsParams object
// with the ability to set a timeout on a request.
func NewDeleteGiteaCredentialsParamsWithTimeout(timeout time.Duration) *DeleteGiteaCredentialsParams {
return &DeleteGiteaCredentialsParams{
timeout: timeout,
}
}
// NewDeleteGiteaCredentialsParamsWithContext creates a new DeleteGiteaCredentialsParams object
// with the ability to set a context for a request.
func NewDeleteGiteaCredentialsParamsWithContext(ctx context.Context) *DeleteGiteaCredentialsParams {
return &DeleteGiteaCredentialsParams{
Context: ctx,
}
}
// NewDeleteGiteaCredentialsParamsWithHTTPClient creates a new DeleteGiteaCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewDeleteGiteaCredentialsParamsWithHTTPClient(client *http.Client) *DeleteGiteaCredentialsParams {
return &DeleteGiteaCredentialsParams{
HTTPClient: client,
}
}
/*
DeleteGiteaCredentialsParams contains all the parameters to send to the API endpoint
for the delete gitea credentials operation.
Typically these are written to a http.Request.
*/
type DeleteGiteaCredentialsParams struct {
/* ID.
ID of the Gitea credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the delete gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGiteaCredentialsParams) WithDefaults() *DeleteGiteaCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the delete gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGiteaCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) WithTimeout(timeout time.Duration) *DeleteGiteaCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) WithContext(ctx context.Context) *DeleteGiteaCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) WithHTTPClient(client *http.Client) *DeleteGiteaCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) WithID(id int64) *DeleteGiteaCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the delete gitea credentials params
func (o *DeleteGiteaCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *DeleteGiteaCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,106 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
)
// DeleteGiteaCredentialsReader is a Reader for the DeleteGiteaCredentials structure.
type DeleteGiteaCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *DeleteGiteaCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
result := NewDeleteGiteaCredentialsDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
// NewDeleteGiteaCredentialsDefault creates a DeleteGiteaCredentialsDefault with default headers values
func NewDeleteGiteaCredentialsDefault(code int) *DeleteGiteaCredentialsDefault {
return &DeleteGiteaCredentialsDefault{
_statusCode: code,
}
}
/*
DeleteGiteaCredentialsDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type DeleteGiteaCredentialsDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this delete gitea credentials default response has a 2xx status code
func (o *DeleteGiteaCredentialsDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this delete gitea credentials default response has a 3xx status code
func (o *DeleteGiteaCredentialsDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this delete gitea credentials default response has a 4xx status code
func (o *DeleteGiteaCredentialsDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this delete gitea credentials default response has a 5xx status code
func (o *DeleteGiteaCredentialsDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this delete gitea credentials default response a status code equal to that given
func (o *DeleteGiteaCredentialsDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the delete gitea credentials default response
func (o *DeleteGiteaCredentialsDefault) Code() int {
return o._statusCode
}
func (o *DeleteGiteaCredentialsDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /gitea/credentials/{id}][%d] DeleteGiteaCredentials default %s", o._statusCode, payload)
}
func (o *DeleteGiteaCredentialsDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /gitea/credentials/{id}][%d] DeleteGiteaCredentials default %s", o._statusCode, payload)
}
func (o *DeleteGiteaCredentialsDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *DeleteGiteaCredentialsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,152 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewGetCredentialsParams creates a new GetCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewGetCredentialsParams() *GetCredentialsParams {
return &GetCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetCredentialsParamsWithTimeout creates a new GetCredentialsParams object
// with the ability to set a timeout on a request.
func NewGetCredentialsParamsWithTimeout(timeout time.Duration) *GetCredentialsParams {
return &GetCredentialsParams{
timeout: timeout,
}
}
// NewGetCredentialsParamsWithContext creates a new GetCredentialsParams object
// with the ability to set a context for a request.
func NewGetCredentialsParamsWithContext(ctx context.Context) *GetCredentialsParams {
return &GetCredentialsParams{
Context: ctx,
}
}
// NewGetCredentialsParamsWithHTTPClient creates a new GetCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewGetCredentialsParamsWithHTTPClient(client *http.Client) *GetCredentialsParams {
return &GetCredentialsParams{
HTTPClient: client,
}
}
/*
GetCredentialsParams contains all the parameters to send to the API endpoint
for the get credentials operation.
Typically these are written to a http.Request.
*/
type GetCredentialsParams struct {
/* ID.
ID of the GitHub credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the get credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetCredentialsParams) WithDefaults() *GetCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the get credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the get credentials params
func (o *GetCredentialsParams) WithTimeout(timeout time.Duration) *GetCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get credentials params
func (o *GetCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get credentials params
func (o *GetCredentialsParams) WithContext(ctx context.Context) *GetCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get credentials params
func (o *GetCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get credentials params
func (o *GetCredentialsParams) WithHTTPClient(client *http.Client) *GetCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get credentials params
func (o *GetCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the get credentials params
func (o *GetCredentialsParams) WithID(id int64) *GetCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the get credentials params
func (o *GetCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *GetCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// GetCredentialsReader is a Reader for the GetCredentials structure.
type GetCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewGetCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /github/credentials/{id}] GetCredentials", response, response.Code())
}
}
// NewGetCredentialsOK creates a GetCredentialsOK with default headers values
func NewGetCredentialsOK() *GetCredentialsOK {
return &GetCredentialsOK{}
}
/*
GetCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type GetCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this get credentials o k response has a 2xx status code
func (o *GetCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this get credentials o k response has a 3xx status code
func (o *GetCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this get credentials o k response has a 4xx status code
func (o *GetCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this get credentials o k response has a 5xx status code
func (o *GetCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this get credentials o k response a status code equal to that given
func (o *GetCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the get credentials o k response
func (o *GetCredentialsOK) Code() int {
return 200
}
func (o *GetCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials/{id}][%d] getCredentialsOK %s", 200, payload)
}
func (o *GetCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials/{id}][%d] getCredentialsOK %s", 200, payload)
}
func (o *GetCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *GetCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetCredentialsBadRequest creates a GetCredentialsBadRequest with default headers values
func NewGetCredentialsBadRequest() *GetCredentialsBadRequest {
return &GetCredentialsBadRequest{}
}
/*
GetCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type GetCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this get credentials bad request response has a 2xx status code
func (o *GetCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this get credentials bad request response has a 3xx status code
func (o *GetCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this get credentials bad request response has a 4xx status code
func (o *GetCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this get credentials bad request response has a 5xx status code
func (o *GetCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this get credentials bad request response a status code equal to that given
func (o *GetCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the get credentials bad request response
func (o *GetCredentialsBadRequest) Code() int {
return 400
}
func (o *GetCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials/{id}][%d] getCredentialsBadRequest %s", 400, payload)
}
func (o *GetCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials/{id}][%d] getCredentialsBadRequest %s", 400, payload)
}
func (o *GetCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *GetCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,152 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewGetGiteaCredentialsParams creates a new GetGiteaCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewGetGiteaCredentialsParams() *GetGiteaCredentialsParams {
return &GetGiteaCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetGiteaCredentialsParamsWithTimeout creates a new GetGiteaCredentialsParams object
// with the ability to set a timeout on a request.
func NewGetGiteaCredentialsParamsWithTimeout(timeout time.Duration) *GetGiteaCredentialsParams {
return &GetGiteaCredentialsParams{
timeout: timeout,
}
}
// NewGetGiteaCredentialsParamsWithContext creates a new GetGiteaCredentialsParams object
// with the ability to set a context for a request.
func NewGetGiteaCredentialsParamsWithContext(ctx context.Context) *GetGiteaCredentialsParams {
return &GetGiteaCredentialsParams{
Context: ctx,
}
}
// NewGetGiteaCredentialsParamsWithHTTPClient creates a new GetGiteaCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewGetGiteaCredentialsParamsWithHTTPClient(client *http.Client) *GetGiteaCredentialsParams {
return &GetGiteaCredentialsParams{
HTTPClient: client,
}
}
/*
GetGiteaCredentialsParams contains all the parameters to send to the API endpoint
for the get gitea credentials operation.
Typically these are written to a http.Request.
*/
type GetGiteaCredentialsParams struct {
/* ID.
ID of the Gitea credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the get gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGiteaCredentialsParams) WithDefaults() *GetGiteaCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the get gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGiteaCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the get gitea credentials params
func (o *GetGiteaCredentialsParams) WithTimeout(timeout time.Duration) *GetGiteaCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get gitea credentials params
func (o *GetGiteaCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get gitea credentials params
func (o *GetGiteaCredentialsParams) WithContext(ctx context.Context) *GetGiteaCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get gitea credentials params
func (o *GetGiteaCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get gitea credentials params
func (o *GetGiteaCredentialsParams) WithHTTPClient(client *http.Client) *GetGiteaCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get gitea credentials params
func (o *GetGiteaCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the get gitea credentials params
func (o *GetGiteaCredentialsParams) WithID(id int64) *GetGiteaCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the get gitea credentials params
func (o *GetGiteaCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *GetGiteaCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// GetGiteaCredentialsReader is a Reader for the GetGiteaCredentials structure.
type GetGiteaCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetGiteaCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetGiteaCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewGetGiteaCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /gitea/credentials/{id}] GetGiteaCredentials", response, response.Code())
}
}
// NewGetGiteaCredentialsOK creates a GetGiteaCredentialsOK with default headers values
func NewGetGiteaCredentialsOK() *GetGiteaCredentialsOK {
return &GetGiteaCredentialsOK{}
}
/*
GetGiteaCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type GetGiteaCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this get gitea credentials o k response has a 2xx status code
func (o *GetGiteaCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this get gitea credentials o k response has a 3xx status code
func (o *GetGiteaCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this get gitea credentials o k response has a 4xx status code
func (o *GetGiteaCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this get gitea credentials o k response has a 5xx status code
func (o *GetGiteaCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this get gitea credentials o k response a status code equal to that given
func (o *GetGiteaCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the get gitea credentials o k response
func (o *GetGiteaCredentialsOK) Code() int {
return 200
}
func (o *GetGiteaCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials/{id}][%d] getGiteaCredentialsOK %s", 200, payload)
}
func (o *GetGiteaCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials/{id}][%d] getGiteaCredentialsOK %s", 200, payload)
}
func (o *GetGiteaCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *GetGiteaCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetGiteaCredentialsBadRequest creates a GetGiteaCredentialsBadRequest with default headers values
func NewGetGiteaCredentialsBadRequest() *GetGiteaCredentialsBadRequest {
return &GetGiteaCredentialsBadRequest{}
}
/*
GetGiteaCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type GetGiteaCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this get gitea credentials bad request response has a 2xx status code
func (o *GetGiteaCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this get gitea credentials bad request response has a 3xx status code
func (o *GetGiteaCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this get gitea credentials bad request response has a 4xx status code
func (o *GetGiteaCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this get gitea credentials bad request response has a 5xx status code
func (o *GetGiteaCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this get gitea credentials bad request response a status code equal to that given
func (o *GetGiteaCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the get gitea credentials bad request response
func (o *GetGiteaCredentialsBadRequest) Code() int {
return 400
}
func (o *GetGiteaCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials/{id}][%d] getGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *GetGiteaCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials/{id}][%d] getGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *GetGiteaCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *GetGiteaCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -6,6 +6,7 @@ package credentials
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -37,7 +38,7 @@ func (o *ListCredentialsReader) ReadResponse(response runtime.ClientResponse, co
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /credentials] ListCredentials", response, response.Code())
return nil, runtime.NewAPIError("[GET /github/credentials] ListCredentials", response, response.Code())
}
}
@ -86,11 +87,13 @@ func (o *ListCredentialsOK) Code() int {
}
func (o *ListCredentialsOK) Error() string {
return fmt.Sprintf("[GET /credentials][%d] listCredentialsOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials][%d] listCredentialsOK %s", 200, payload)
}
func (o *ListCredentialsOK) String() string {
return fmt.Sprintf("[GET /credentials][%d] listCredentialsOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials][%d] listCredentialsOK %s", 200, payload)
}
func (o *ListCredentialsOK) GetPayload() garm_params.Credentials {
@ -152,11 +155,13 @@ func (o *ListCredentialsBadRequest) Code() int {
}
func (o *ListCredentialsBadRequest) Error() string {
return fmt.Sprintf("[GET /credentials][%d] listCredentialsBadRequest %+v", 400, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials][%d] listCredentialsBadRequest %s", 400, payload)
}
func (o *ListCredentialsBadRequest) String() string {
return fmt.Sprintf("[GET /credentials][%d] listCredentialsBadRequest %+v", 400, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/credentials][%d] listCredentialsBadRequest %s", 400, payload)
}
func (o *ListCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -0,0 +1,128 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewListGiteaCredentialsParams creates a new ListGiteaCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewListGiteaCredentialsParams() *ListGiteaCredentialsParams {
return &ListGiteaCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewListGiteaCredentialsParamsWithTimeout creates a new ListGiteaCredentialsParams object
// with the ability to set a timeout on a request.
func NewListGiteaCredentialsParamsWithTimeout(timeout time.Duration) *ListGiteaCredentialsParams {
return &ListGiteaCredentialsParams{
timeout: timeout,
}
}
// NewListGiteaCredentialsParamsWithContext creates a new ListGiteaCredentialsParams object
// with the ability to set a context for a request.
func NewListGiteaCredentialsParamsWithContext(ctx context.Context) *ListGiteaCredentialsParams {
return &ListGiteaCredentialsParams{
Context: ctx,
}
}
// NewListGiteaCredentialsParamsWithHTTPClient creates a new ListGiteaCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewListGiteaCredentialsParamsWithHTTPClient(client *http.Client) *ListGiteaCredentialsParams {
return &ListGiteaCredentialsParams{
HTTPClient: client,
}
}
/*
ListGiteaCredentialsParams contains all the parameters to send to the API endpoint
for the list gitea credentials operation.
Typically these are written to a http.Request.
*/
type ListGiteaCredentialsParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the list gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGiteaCredentialsParams) WithDefaults() *ListGiteaCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the list gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGiteaCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the list gitea credentials params
func (o *ListGiteaCredentialsParams) WithTimeout(timeout time.Duration) *ListGiteaCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the list gitea credentials params
func (o *ListGiteaCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the list gitea credentials params
func (o *ListGiteaCredentialsParams) WithContext(ctx context.Context) *ListGiteaCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the list gitea credentials params
func (o *ListGiteaCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the list gitea credentials params
func (o *ListGiteaCredentialsParams) WithHTTPClient(client *http.Client) *ListGiteaCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the list gitea credentials params
func (o *ListGiteaCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *ListGiteaCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// ListGiteaCredentialsReader is a Reader for the ListGiteaCredentials structure.
type ListGiteaCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ListGiteaCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewListGiteaCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewListGiteaCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /gitea/credentials] ListGiteaCredentials", response, response.Code())
}
}
// NewListGiteaCredentialsOK creates a ListGiteaCredentialsOK with default headers values
func NewListGiteaCredentialsOK() *ListGiteaCredentialsOK {
return &ListGiteaCredentialsOK{}
}
/*
ListGiteaCredentialsOK describes a response with status code 200, with default header values.
Credentials
*/
type ListGiteaCredentialsOK struct {
Payload garm_params.Credentials
}
// IsSuccess returns true when this list gitea credentials o k response has a 2xx status code
func (o *ListGiteaCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this list gitea credentials o k response has a 3xx status code
func (o *ListGiteaCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this list gitea credentials o k response has a 4xx status code
func (o *ListGiteaCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this list gitea credentials o k response has a 5xx status code
func (o *ListGiteaCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this list gitea credentials o k response a status code equal to that given
func (o *ListGiteaCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the list gitea credentials o k response
func (o *ListGiteaCredentialsOK) Code() int {
return 200
}
func (o *ListGiteaCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials][%d] listGiteaCredentialsOK %s", 200, payload)
}
func (o *ListGiteaCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials][%d] listGiteaCredentialsOK %s", 200, payload)
}
func (o *ListGiteaCredentialsOK) GetPayload() garm_params.Credentials {
return o.Payload
}
func (o *ListGiteaCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewListGiteaCredentialsBadRequest creates a ListGiteaCredentialsBadRequest with default headers values
func NewListGiteaCredentialsBadRequest() *ListGiteaCredentialsBadRequest {
return &ListGiteaCredentialsBadRequest{}
}
/*
ListGiteaCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type ListGiteaCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this list gitea credentials bad request response has a 2xx status code
func (o *ListGiteaCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list gitea credentials bad request response has a 3xx status code
func (o *ListGiteaCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this list gitea credentials bad request response has a 4xx status code
func (o *ListGiteaCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this list gitea credentials bad request response has a 5xx status code
func (o *ListGiteaCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this list gitea credentials bad request response a status code equal to that given
func (o *ListGiteaCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the list gitea credentials bad request response
func (o *ListGiteaCredentialsBadRequest) Code() int {
return 400
}
func (o *ListGiteaCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials][%d] listGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *ListGiteaCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/credentials][%d] listGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *ListGiteaCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *ListGiteaCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,174 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
garm_params "github.com/cloudbase/garm/params"
)
// NewUpdateCredentialsParams creates a new UpdateCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewUpdateCredentialsParams() *UpdateCredentialsParams {
return &UpdateCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewUpdateCredentialsParamsWithTimeout creates a new UpdateCredentialsParams object
// with the ability to set a timeout on a request.
func NewUpdateCredentialsParamsWithTimeout(timeout time.Duration) *UpdateCredentialsParams {
return &UpdateCredentialsParams{
timeout: timeout,
}
}
// NewUpdateCredentialsParamsWithContext creates a new UpdateCredentialsParams object
// with the ability to set a context for a request.
func NewUpdateCredentialsParamsWithContext(ctx context.Context) *UpdateCredentialsParams {
return &UpdateCredentialsParams{
Context: ctx,
}
}
// NewUpdateCredentialsParamsWithHTTPClient creates a new UpdateCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewUpdateCredentialsParamsWithHTTPClient(client *http.Client) *UpdateCredentialsParams {
return &UpdateCredentialsParams{
HTTPClient: client,
}
}
/*
UpdateCredentialsParams contains all the parameters to send to the API endpoint
for the update credentials operation.
Typically these are written to a http.Request.
*/
type UpdateCredentialsParams struct {
/* Body.
Parameters used when updating a GitHub credential.
*/
Body garm_params.UpdateGithubCredentialsParams
/* ID.
ID of the GitHub credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the update credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateCredentialsParams) WithDefaults() *UpdateCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the update credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the update credentials params
func (o *UpdateCredentialsParams) WithTimeout(timeout time.Duration) *UpdateCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the update credentials params
func (o *UpdateCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the update credentials params
func (o *UpdateCredentialsParams) WithContext(ctx context.Context) *UpdateCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the update credentials params
func (o *UpdateCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the update credentials params
func (o *UpdateCredentialsParams) WithHTTPClient(client *http.Client) *UpdateCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the update credentials params
func (o *UpdateCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the update credentials params
func (o *UpdateCredentialsParams) WithBody(body garm_params.UpdateGithubCredentialsParams) *UpdateCredentialsParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the update credentials params
func (o *UpdateCredentialsParams) SetBody(body garm_params.UpdateGithubCredentialsParams) {
o.Body = body
}
// WithID adds the id to the update credentials params
func (o *UpdateCredentialsParams) WithID(id int64) *UpdateCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the update credentials params
func (o *UpdateCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *UpdateCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// UpdateCredentialsReader is a Reader for the UpdateCredentials structure.
type UpdateCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *UpdateCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewUpdateCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewUpdateCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[PUT /github/credentials/{id}] UpdateCredentials", response, response.Code())
}
}
// NewUpdateCredentialsOK creates a UpdateCredentialsOK with default headers values
func NewUpdateCredentialsOK() *UpdateCredentialsOK {
return &UpdateCredentialsOK{}
}
/*
UpdateCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type UpdateCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this update credentials o k response has a 2xx status code
func (o *UpdateCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this update credentials o k response has a 3xx status code
func (o *UpdateCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this update credentials o k response has a 4xx status code
func (o *UpdateCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this update credentials o k response has a 5xx status code
func (o *UpdateCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this update credentials o k response a status code equal to that given
func (o *UpdateCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the update credentials o k response
func (o *UpdateCredentialsOK) Code() int {
return 200
}
func (o *UpdateCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/credentials/{id}][%d] updateCredentialsOK %s", 200, payload)
}
func (o *UpdateCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/credentials/{id}][%d] updateCredentialsOK %s", 200, payload)
}
func (o *UpdateCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *UpdateCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewUpdateCredentialsBadRequest creates a UpdateCredentialsBadRequest with default headers values
func NewUpdateCredentialsBadRequest() *UpdateCredentialsBadRequest {
return &UpdateCredentialsBadRequest{}
}
/*
UpdateCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type UpdateCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this update credentials bad request response has a 2xx status code
func (o *UpdateCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this update credentials bad request response has a 3xx status code
func (o *UpdateCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this update credentials bad request response has a 4xx status code
func (o *UpdateCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this update credentials bad request response has a 5xx status code
func (o *UpdateCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this update credentials bad request response a status code equal to that given
func (o *UpdateCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the update credentials bad request response
func (o *UpdateCredentialsBadRequest) Code() int {
return 400
}
func (o *UpdateCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/credentials/{id}][%d] updateCredentialsBadRequest %s", 400, payload)
}
func (o *UpdateCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/credentials/{id}][%d] updateCredentialsBadRequest %s", 400, payload)
}
func (o *UpdateCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *UpdateCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,174 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
garm_params "github.com/cloudbase/garm/params"
)
// NewUpdateGiteaCredentialsParams creates a new UpdateGiteaCredentialsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewUpdateGiteaCredentialsParams() *UpdateGiteaCredentialsParams {
return &UpdateGiteaCredentialsParams{
timeout: cr.DefaultTimeout,
}
}
// NewUpdateGiteaCredentialsParamsWithTimeout creates a new UpdateGiteaCredentialsParams object
// with the ability to set a timeout on a request.
func NewUpdateGiteaCredentialsParamsWithTimeout(timeout time.Duration) *UpdateGiteaCredentialsParams {
return &UpdateGiteaCredentialsParams{
timeout: timeout,
}
}
// NewUpdateGiteaCredentialsParamsWithContext creates a new UpdateGiteaCredentialsParams object
// with the ability to set a context for a request.
func NewUpdateGiteaCredentialsParamsWithContext(ctx context.Context) *UpdateGiteaCredentialsParams {
return &UpdateGiteaCredentialsParams{
Context: ctx,
}
}
// NewUpdateGiteaCredentialsParamsWithHTTPClient creates a new UpdateGiteaCredentialsParams object
// with the ability to set a custom HTTPClient for a request.
func NewUpdateGiteaCredentialsParamsWithHTTPClient(client *http.Client) *UpdateGiteaCredentialsParams {
return &UpdateGiteaCredentialsParams{
HTTPClient: client,
}
}
/*
UpdateGiteaCredentialsParams contains all the parameters to send to the API endpoint
for the update gitea credentials operation.
Typically these are written to a http.Request.
*/
type UpdateGiteaCredentialsParams struct {
/* Body.
Parameters used when updating a Gitea credential.
*/
Body garm_params.UpdateGiteaCredentialsParams
/* ID.
ID of the Gitea credential.
*/
ID int64
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the update gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGiteaCredentialsParams) WithDefaults() *UpdateGiteaCredentialsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the update gitea credentials params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGiteaCredentialsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) WithTimeout(timeout time.Duration) *UpdateGiteaCredentialsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) WithContext(ctx context.Context) *UpdateGiteaCredentialsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) WithHTTPClient(client *http.Client) *UpdateGiteaCredentialsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) WithBody(body garm_params.UpdateGiteaCredentialsParams) *UpdateGiteaCredentialsParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) SetBody(body garm_params.UpdateGiteaCredentialsParams) {
o.Body = body
}
// WithID adds the id to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) WithID(id int64) *UpdateGiteaCredentialsParams {
o.SetID(id)
return o
}
// SetID adds the id to the update gitea credentials params
func (o *UpdateGiteaCredentialsParams) SetID(id int64) {
o.ID = id
}
// WriteToRequest writes these params to a swagger request
func (o *UpdateGiteaCredentialsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package credentials
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// UpdateGiteaCredentialsReader is a Reader for the UpdateGiteaCredentials structure.
type UpdateGiteaCredentialsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *UpdateGiteaCredentialsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewUpdateGiteaCredentialsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewUpdateGiteaCredentialsBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[PUT /gitea/credentials/{id}] UpdateGiteaCredentials", response, response.Code())
}
}
// NewUpdateGiteaCredentialsOK creates a UpdateGiteaCredentialsOK with default headers values
func NewUpdateGiteaCredentialsOK() *UpdateGiteaCredentialsOK {
return &UpdateGiteaCredentialsOK{}
}
/*
UpdateGiteaCredentialsOK describes a response with status code 200, with default header values.
ForgeCredentials
*/
type UpdateGiteaCredentialsOK struct {
Payload garm_params.ForgeCredentials
}
// IsSuccess returns true when this update gitea credentials o k response has a 2xx status code
func (o *UpdateGiteaCredentialsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this update gitea credentials o k response has a 3xx status code
func (o *UpdateGiteaCredentialsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this update gitea credentials o k response has a 4xx status code
func (o *UpdateGiteaCredentialsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this update gitea credentials o k response has a 5xx status code
func (o *UpdateGiteaCredentialsOK) IsServerError() bool {
return false
}
// IsCode returns true when this update gitea credentials o k response a status code equal to that given
func (o *UpdateGiteaCredentialsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the update gitea credentials o k response
func (o *UpdateGiteaCredentialsOK) Code() int {
return 200
}
func (o *UpdateGiteaCredentialsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/credentials/{id}][%d] updateGiteaCredentialsOK %s", 200, payload)
}
func (o *UpdateGiteaCredentialsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/credentials/{id}][%d] updateGiteaCredentialsOK %s", 200, payload)
}
func (o *UpdateGiteaCredentialsOK) GetPayload() garm_params.ForgeCredentials {
return o.Payload
}
func (o *UpdateGiteaCredentialsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewUpdateGiteaCredentialsBadRequest creates a UpdateGiteaCredentialsBadRequest with default headers values
func NewUpdateGiteaCredentialsBadRequest() *UpdateGiteaCredentialsBadRequest {
return &UpdateGiteaCredentialsBadRequest{}
}
/*
UpdateGiteaCredentialsBadRequest describes a response with status code 400, with default header values.
APIErrorResponse
*/
type UpdateGiteaCredentialsBadRequest struct {
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this update gitea credentials bad request response has a 2xx status code
func (o *UpdateGiteaCredentialsBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this update gitea credentials bad request response has a 3xx status code
func (o *UpdateGiteaCredentialsBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this update gitea credentials bad request response has a 4xx status code
func (o *UpdateGiteaCredentialsBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this update gitea credentials bad request response has a 5xx status code
func (o *UpdateGiteaCredentialsBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this update gitea credentials bad request response a status code equal to that given
func (o *UpdateGiteaCredentialsBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the update gitea credentials bad request response
func (o *UpdateGiteaCredentialsBadRequest) Code() int {
return 400
}
func (o *UpdateGiteaCredentialsBadRequest) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/credentials/{id}][%d] updateGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *UpdateGiteaCredentialsBadRequest) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/credentials/{id}][%d] updateGiteaCredentialsBadRequest %s", 400, payload)
}
func (o *UpdateGiteaCredentialsBadRequest) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *UpdateGiteaCredentialsBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewCreateGiteaEndpointParams creates a new CreateGiteaEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCreateGiteaEndpointParams() *CreateGiteaEndpointParams {
return &CreateGiteaEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewCreateGiteaEndpointParamsWithTimeout creates a new CreateGiteaEndpointParams object
// with the ability to set a timeout on a request.
func NewCreateGiteaEndpointParamsWithTimeout(timeout time.Duration) *CreateGiteaEndpointParams {
return &CreateGiteaEndpointParams{
timeout: timeout,
}
}
// NewCreateGiteaEndpointParamsWithContext creates a new CreateGiteaEndpointParams object
// with the ability to set a context for a request.
func NewCreateGiteaEndpointParamsWithContext(ctx context.Context) *CreateGiteaEndpointParams {
return &CreateGiteaEndpointParams{
Context: ctx,
}
}
// NewCreateGiteaEndpointParamsWithHTTPClient creates a new CreateGiteaEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewCreateGiteaEndpointParamsWithHTTPClient(client *http.Client) *CreateGiteaEndpointParams {
return &CreateGiteaEndpointParams{
HTTPClient: client,
}
}
/*
CreateGiteaEndpointParams contains all the parameters to send to the API endpoint
for the create gitea endpoint operation.
Typically these are written to a http.Request.
*/
type CreateGiteaEndpointParams struct {
/* Body.
Parameters used when creating a Gitea endpoint.
*/
Body garm_params.CreateGiteaEndpointParams
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the create gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGiteaEndpointParams) WithDefaults() *CreateGiteaEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the create gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGiteaEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) WithTimeout(timeout time.Duration) *CreateGiteaEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) WithContext(ctx context.Context) *CreateGiteaEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) WithHTTPClient(client *http.Client) *CreateGiteaEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) WithBody(body garm_params.CreateGiteaEndpointParams) *CreateGiteaEndpointParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the create gitea endpoint params
func (o *CreateGiteaEndpointParams) SetBody(body garm_params.CreateGiteaEndpointParams) {
o.Body = body
}
// WriteToRequest writes these params to a swagger request
func (o *CreateGiteaEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// CreateGiteaEndpointReader is a Reader for the CreateGiteaEndpoint structure.
type CreateGiteaEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *CreateGiteaEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewCreateGiteaEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewCreateGiteaEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewCreateGiteaEndpointOK creates a CreateGiteaEndpointOK with default headers values
func NewCreateGiteaEndpointOK() *CreateGiteaEndpointOK {
return &CreateGiteaEndpointOK{}
}
/*
CreateGiteaEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type CreateGiteaEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this create gitea endpoint o k response has a 2xx status code
func (o *CreateGiteaEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this create gitea endpoint o k response has a 3xx status code
func (o *CreateGiteaEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this create gitea endpoint o k response has a 4xx status code
func (o *CreateGiteaEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this create gitea endpoint o k response has a 5xx status code
func (o *CreateGiteaEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this create gitea endpoint o k response a status code equal to that given
func (o *CreateGiteaEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the create gitea endpoint o k response
func (o *CreateGiteaEndpointOK) Code() int {
return 200
}
func (o *CreateGiteaEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/endpoints][%d] createGiteaEndpointOK %s", 200, payload)
}
func (o *CreateGiteaEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/endpoints][%d] createGiteaEndpointOK %s", 200, payload)
}
func (o *CreateGiteaEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *CreateGiteaEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewCreateGiteaEndpointDefault creates a CreateGiteaEndpointDefault with default headers values
func NewCreateGiteaEndpointDefault(code int) *CreateGiteaEndpointDefault {
return &CreateGiteaEndpointDefault{
_statusCode: code,
}
}
/*
CreateGiteaEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type CreateGiteaEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this create gitea endpoint default response has a 2xx status code
func (o *CreateGiteaEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this create gitea endpoint default response has a 3xx status code
func (o *CreateGiteaEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this create gitea endpoint default response has a 4xx status code
func (o *CreateGiteaEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this create gitea endpoint default response has a 5xx status code
func (o *CreateGiteaEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this create gitea endpoint default response a status code equal to that given
func (o *CreateGiteaEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the create gitea endpoint default response
func (o *CreateGiteaEndpointDefault) Code() int {
return o._statusCode
}
func (o *CreateGiteaEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/endpoints][%d] CreateGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *CreateGiteaEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /gitea/endpoints][%d] CreateGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *CreateGiteaEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *CreateGiteaEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewCreateGithubEndpointParams creates a new CreateGithubEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCreateGithubEndpointParams() *CreateGithubEndpointParams {
return &CreateGithubEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewCreateGithubEndpointParamsWithTimeout creates a new CreateGithubEndpointParams object
// with the ability to set a timeout on a request.
func NewCreateGithubEndpointParamsWithTimeout(timeout time.Duration) *CreateGithubEndpointParams {
return &CreateGithubEndpointParams{
timeout: timeout,
}
}
// NewCreateGithubEndpointParamsWithContext creates a new CreateGithubEndpointParams object
// with the ability to set a context for a request.
func NewCreateGithubEndpointParamsWithContext(ctx context.Context) *CreateGithubEndpointParams {
return &CreateGithubEndpointParams{
Context: ctx,
}
}
// NewCreateGithubEndpointParamsWithHTTPClient creates a new CreateGithubEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewCreateGithubEndpointParamsWithHTTPClient(client *http.Client) *CreateGithubEndpointParams {
return &CreateGithubEndpointParams{
HTTPClient: client,
}
}
/*
CreateGithubEndpointParams contains all the parameters to send to the API endpoint
for the create github endpoint operation.
Typically these are written to a http.Request.
*/
type CreateGithubEndpointParams struct {
/* Body.
Parameters used when creating a GitHub endpoint.
*/
Body garm_params.CreateGithubEndpointParams
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the create github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGithubEndpointParams) WithDefaults() *CreateGithubEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the create github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateGithubEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the create github endpoint params
func (o *CreateGithubEndpointParams) WithTimeout(timeout time.Duration) *CreateGithubEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the create github endpoint params
func (o *CreateGithubEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the create github endpoint params
func (o *CreateGithubEndpointParams) WithContext(ctx context.Context) *CreateGithubEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the create github endpoint params
func (o *CreateGithubEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the create github endpoint params
func (o *CreateGithubEndpointParams) WithHTTPClient(client *http.Client) *CreateGithubEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the create github endpoint params
func (o *CreateGithubEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the create github endpoint params
func (o *CreateGithubEndpointParams) WithBody(body garm_params.CreateGithubEndpointParams) *CreateGithubEndpointParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the create github endpoint params
func (o *CreateGithubEndpointParams) SetBody(body garm_params.CreateGithubEndpointParams) {
o.Body = body
}
// WriteToRequest writes these params to a swagger request
func (o *CreateGithubEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// CreateGithubEndpointReader is a Reader for the CreateGithubEndpoint structure.
type CreateGithubEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *CreateGithubEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewCreateGithubEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewCreateGithubEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewCreateGithubEndpointOK creates a CreateGithubEndpointOK with default headers values
func NewCreateGithubEndpointOK() *CreateGithubEndpointOK {
return &CreateGithubEndpointOK{}
}
/*
CreateGithubEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type CreateGithubEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this create github endpoint o k response has a 2xx status code
func (o *CreateGithubEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this create github endpoint o k response has a 3xx status code
func (o *CreateGithubEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this create github endpoint o k response has a 4xx status code
func (o *CreateGithubEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this create github endpoint o k response has a 5xx status code
func (o *CreateGithubEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this create github endpoint o k response a status code equal to that given
func (o *CreateGithubEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the create github endpoint o k response
func (o *CreateGithubEndpointOK) Code() int {
return 200
}
func (o *CreateGithubEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/endpoints][%d] createGithubEndpointOK %s", 200, payload)
}
func (o *CreateGithubEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/endpoints][%d] createGithubEndpointOK %s", 200, payload)
}
func (o *CreateGithubEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *CreateGithubEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewCreateGithubEndpointDefault creates a CreateGithubEndpointDefault with default headers values
func NewCreateGithubEndpointDefault(code int) *CreateGithubEndpointDefault {
return &CreateGithubEndpointDefault{
_statusCode: code,
}
}
/*
CreateGithubEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type CreateGithubEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this create github endpoint default response has a 2xx status code
func (o *CreateGithubEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this create github endpoint default response has a 3xx status code
func (o *CreateGithubEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this create github endpoint default response has a 4xx status code
func (o *CreateGithubEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this create github endpoint default response has a 5xx status code
func (o *CreateGithubEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this create github endpoint default response a status code equal to that given
func (o *CreateGithubEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the create github endpoint default response
func (o *CreateGithubEndpointDefault) Code() int {
return o._statusCode
}
func (o *CreateGithubEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/endpoints][%d] CreateGithubEndpoint default %s", o._statusCode, payload)
}
func (o *CreateGithubEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /github/endpoints][%d] CreateGithubEndpoint default %s", o._statusCode, payload)
}
func (o *CreateGithubEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *CreateGithubEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewDeleteGiteaEndpointParams creates a new DeleteGiteaEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewDeleteGiteaEndpointParams() *DeleteGiteaEndpointParams {
return &DeleteGiteaEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewDeleteGiteaEndpointParamsWithTimeout creates a new DeleteGiteaEndpointParams object
// with the ability to set a timeout on a request.
func NewDeleteGiteaEndpointParamsWithTimeout(timeout time.Duration) *DeleteGiteaEndpointParams {
return &DeleteGiteaEndpointParams{
timeout: timeout,
}
}
// NewDeleteGiteaEndpointParamsWithContext creates a new DeleteGiteaEndpointParams object
// with the ability to set a context for a request.
func NewDeleteGiteaEndpointParamsWithContext(ctx context.Context) *DeleteGiteaEndpointParams {
return &DeleteGiteaEndpointParams{
Context: ctx,
}
}
// NewDeleteGiteaEndpointParamsWithHTTPClient creates a new DeleteGiteaEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewDeleteGiteaEndpointParamsWithHTTPClient(client *http.Client) *DeleteGiteaEndpointParams {
return &DeleteGiteaEndpointParams{
HTTPClient: client,
}
}
/*
DeleteGiteaEndpointParams contains all the parameters to send to the API endpoint
for the delete gitea endpoint operation.
Typically these are written to a http.Request.
*/
type DeleteGiteaEndpointParams struct {
/* Name.
The name of the Gitea endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the delete gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGiteaEndpointParams) WithDefaults() *DeleteGiteaEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the delete gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGiteaEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) WithTimeout(timeout time.Duration) *DeleteGiteaEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) WithContext(ctx context.Context) *DeleteGiteaEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) WithHTTPClient(client *http.Client) *DeleteGiteaEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithName adds the name to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) WithName(name string) *DeleteGiteaEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the delete gitea endpoint params
func (o *DeleteGiteaEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *DeleteGiteaEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,106 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
)
// DeleteGiteaEndpointReader is a Reader for the DeleteGiteaEndpoint structure.
type DeleteGiteaEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *DeleteGiteaEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
result := NewDeleteGiteaEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
// NewDeleteGiteaEndpointDefault creates a DeleteGiteaEndpointDefault with default headers values
func NewDeleteGiteaEndpointDefault(code int) *DeleteGiteaEndpointDefault {
return &DeleteGiteaEndpointDefault{
_statusCode: code,
}
}
/*
DeleteGiteaEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type DeleteGiteaEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this delete gitea endpoint default response has a 2xx status code
func (o *DeleteGiteaEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this delete gitea endpoint default response has a 3xx status code
func (o *DeleteGiteaEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this delete gitea endpoint default response has a 4xx status code
func (o *DeleteGiteaEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this delete gitea endpoint default response has a 5xx status code
func (o *DeleteGiteaEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this delete gitea endpoint default response a status code equal to that given
func (o *DeleteGiteaEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the delete gitea endpoint default response
func (o *DeleteGiteaEndpointDefault) Code() int {
return o._statusCode
}
func (o *DeleteGiteaEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /gitea/endpoints/{name}][%d] DeleteGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *DeleteGiteaEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /gitea/endpoints/{name}][%d] DeleteGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *DeleteGiteaEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *DeleteGiteaEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewDeleteGithubEndpointParams creates a new DeleteGithubEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewDeleteGithubEndpointParams() *DeleteGithubEndpointParams {
return &DeleteGithubEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewDeleteGithubEndpointParamsWithTimeout creates a new DeleteGithubEndpointParams object
// with the ability to set a timeout on a request.
func NewDeleteGithubEndpointParamsWithTimeout(timeout time.Duration) *DeleteGithubEndpointParams {
return &DeleteGithubEndpointParams{
timeout: timeout,
}
}
// NewDeleteGithubEndpointParamsWithContext creates a new DeleteGithubEndpointParams object
// with the ability to set a context for a request.
func NewDeleteGithubEndpointParamsWithContext(ctx context.Context) *DeleteGithubEndpointParams {
return &DeleteGithubEndpointParams{
Context: ctx,
}
}
// NewDeleteGithubEndpointParamsWithHTTPClient creates a new DeleteGithubEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewDeleteGithubEndpointParamsWithHTTPClient(client *http.Client) *DeleteGithubEndpointParams {
return &DeleteGithubEndpointParams{
HTTPClient: client,
}
}
/*
DeleteGithubEndpointParams contains all the parameters to send to the API endpoint
for the delete github endpoint operation.
Typically these are written to a http.Request.
*/
type DeleteGithubEndpointParams struct {
/* Name.
The name of the GitHub endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the delete github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGithubEndpointParams) WithDefaults() *DeleteGithubEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the delete github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *DeleteGithubEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the delete github endpoint params
func (o *DeleteGithubEndpointParams) WithTimeout(timeout time.Duration) *DeleteGithubEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the delete github endpoint params
func (o *DeleteGithubEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the delete github endpoint params
func (o *DeleteGithubEndpointParams) WithContext(ctx context.Context) *DeleteGithubEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the delete github endpoint params
func (o *DeleteGithubEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the delete github endpoint params
func (o *DeleteGithubEndpointParams) WithHTTPClient(client *http.Client) *DeleteGithubEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the delete github endpoint params
func (o *DeleteGithubEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithName adds the name to the delete github endpoint params
func (o *DeleteGithubEndpointParams) WithName(name string) *DeleteGithubEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the delete github endpoint params
func (o *DeleteGithubEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *DeleteGithubEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,106 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
)
// DeleteGithubEndpointReader is a Reader for the DeleteGithubEndpoint structure.
type DeleteGithubEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *DeleteGithubEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
result := NewDeleteGithubEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
// NewDeleteGithubEndpointDefault creates a DeleteGithubEndpointDefault with default headers values
func NewDeleteGithubEndpointDefault(code int) *DeleteGithubEndpointDefault {
return &DeleteGithubEndpointDefault{
_statusCode: code,
}
}
/*
DeleteGithubEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type DeleteGithubEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this delete github endpoint default response has a 2xx status code
func (o *DeleteGithubEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this delete github endpoint default response has a 3xx status code
func (o *DeleteGithubEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this delete github endpoint default response has a 4xx status code
func (o *DeleteGithubEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this delete github endpoint default response has a 5xx status code
func (o *DeleteGithubEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this delete github endpoint default response a status code equal to that given
func (o *DeleteGithubEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the delete github endpoint default response
func (o *DeleteGithubEndpointDefault) Code() int {
return o._statusCode
}
func (o *DeleteGithubEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /github/endpoints/{name}][%d] DeleteGithubEndpoint default %s", o._statusCode, payload)
}
func (o *DeleteGithubEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /github/endpoints/{name}][%d] DeleteGithubEndpoint default %s", o._statusCode, payload)
}
func (o *DeleteGithubEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *DeleteGithubEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,451 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// New creates a new endpoints API client.
func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService {
return &Client{transport: transport, formats: formats}
}
// New creates a new endpoints API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new endpoints API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client for endpoints API
*/
type Client struct {
transport runtime.ClientTransport
formats strfmt.Registry
}
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
type ClientService interface {
CreateGiteaEndpoint(params *CreateGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGiteaEndpointOK, error)
CreateGithubEndpoint(params *CreateGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGithubEndpointOK, error)
DeleteGiteaEndpoint(params *DeleteGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
DeleteGithubEndpoint(params *DeleteGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
GetGiteaEndpoint(params *GetGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGiteaEndpointOK, error)
GetGithubEndpoint(params *GetGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGithubEndpointOK, error)
ListGiteaEndpoints(params *ListGiteaEndpointsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGiteaEndpointsOK, error)
ListGithubEndpoints(params *ListGithubEndpointsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGithubEndpointsOK, error)
UpdateGiteaEndpoint(params *UpdateGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGiteaEndpointOK, error)
UpdateGithubEndpoint(params *UpdateGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGithubEndpointOK, error)
SetTransport(transport runtime.ClientTransport)
}
/*
CreateGiteaEndpoint creates a gitea endpoint
*/
func (a *Client) CreateGiteaEndpoint(params *CreateGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGiteaEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCreateGiteaEndpointParams()
}
op := &runtime.ClientOperation{
ID: "CreateGiteaEndpoint",
Method: "POST",
PathPattern: "/gitea/endpoints",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &CreateGiteaEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*CreateGiteaEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*CreateGiteaEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
CreateGithubEndpoint creates a git hub endpoint
*/
func (a *Client) CreateGithubEndpoint(params *CreateGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateGithubEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCreateGithubEndpointParams()
}
op := &runtime.ClientOperation{
ID: "CreateGithubEndpoint",
Method: "POST",
PathPattern: "/github/endpoints",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &CreateGithubEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*CreateGithubEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*CreateGithubEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
DeleteGiteaEndpoint deletes a gitea endpoint
*/
func (a *Client) DeleteGiteaEndpoint(params *DeleteGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error {
// TODO: Validate the params before sending
if params == nil {
params = NewDeleteGiteaEndpointParams()
}
op := &runtime.ClientOperation{
ID: "DeleteGiteaEndpoint",
Method: "DELETE",
PathPattern: "/gitea/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &DeleteGiteaEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
_, err := a.transport.Submit(op)
if err != nil {
return err
}
return nil
}
/*
DeleteGithubEndpoint deletes a git hub endpoint
*/
func (a *Client) DeleteGithubEndpoint(params *DeleteGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error {
// TODO: Validate the params before sending
if params == nil {
params = NewDeleteGithubEndpointParams()
}
op := &runtime.ClientOperation{
ID: "DeleteGithubEndpoint",
Method: "DELETE",
PathPattern: "/github/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &DeleteGithubEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
_, err := a.transport.Submit(op)
if err != nil {
return err
}
return nil
}
/*
GetGiteaEndpoint gets a gitea endpoint
*/
func (a *Client) GetGiteaEndpoint(params *GetGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGiteaEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetGiteaEndpointParams()
}
op := &runtime.ClientOperation{
ID: "GetGiteaEndpoint",
Method: "GET",
PathPattern: "/gitea/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &GetGiteaEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*GetGiteaEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*GetGiteaEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
GetGithubEndpoint gets a git hub endpoint
*/
func (a *Client) GetGithubEndpoint(params *GetGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetGithubEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetGithubEndpointParams()
}
op := &runtime.ClientOperation{
ID: "GetGithubEndpoint",
Method: "GET",
PathPattern: "/github/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &GetGithubEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*GetGithubEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*GetGithubEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
ListGiteaEndpoints lists all gitea endpoints
*/
func (a *Client) ListGiteaEndpoints(params *ListGiteaEndpointsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGiteaEndpointsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewListGiteaEndpointsParams()
}
op := &runtime.ClientOperation{
ID: "ListGiteaEndpoints",
Method: "GET",
PathPattern: "/gitea/endpoints",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ListGiteaEndpointsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ListGiteaEndpointsOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*ListGiteaEndpointsDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
ListGithubEndpoints lists all git hub endpoints
*/
func (a *Client) ListGithubEndpoints(params *ListGithubEndpointsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListGithubEndpointsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewListGithubEndpointsParams()
}
op := &runtime.ClientOperation{
ID: "ListGithubEndpoints",
Method: "GET",
PathPattern: "/github/endpoints",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ListGithubEndpointsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ListGithubEndpointsOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*ListGithubEndpointsDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
UpdateGiteaEndpoint updates a gitea endpoint
*/
func (a *Client) UpdateGiteaEndpoint(params *UpdateGiteaEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGiteaEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewUpdateGiteaEndpointParams()
}
op := &runtime.ClientOperation{
ID: "UpdateGiteaEndpoint",
Method: "PUT",
PathPattern: "/gitea/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &UpdateGiteaEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*UpdateGiteaEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*UpdateGiteaEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
UpdateGithubEndpoint updates a git hub endpoint
*/
func (a *Client) UpdateGithubEndpoint(params *UpdateGithubEndpointParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateGithubEndpointOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewUpdateGithubEndpointParams()
}
op := &runtime.ClientOperation{
ID: "UpdateGithubEndpoint",
Method: "PUT",
PathPattern: "/github/endpoints/{name}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &UpdateGithubEndpointReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*UpdateGithubEndpointOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*UpdateGithubEndpointDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewGetGiteaEndpointParams creates a new GetGiteaEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewGetGiteaEndpointParams() *GetGiteaEndpointParams {
return &GetGiteaEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetGiteaEndpointParamsWithTimeout creates a new GetGiteaEndpointParams object
// with the ability to set a timeout on a request.
func NewGetGiteaEndpointParamsWithTimeout(timeout time.Duration) *GetGiteaEndpointParams {
return &GetGiteaEndpointParams{
timeout: timeout,
}
}
// NewGetGiteaEndpointParamsWithContext creates a new GetGiteaEndpointParams object
// with the ability to set a context for a request.
func NewGetGiteaEndpointParamsWithContext(ctx context.Context) *GetGiteaEndpointParams {
return &GetGiteaEndpointParams{
Context: ctx,
}
}
// NewGetGiteaEndpointParamsWithHTTPClient creates a new GetGiteaEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewGetGiteaEndpointParamsWithHTTPClient(client *http.Client) *GetGiteaEndpointParams {
return &GetGiteaEndpointParams{
HTTPClient: client,
}
}
/*
GetGiteaEndpointParams contains all the parameters to send to the API endpoint
for the get gitea endpoint operation.
Typically these are written to a http.Request.
*/
type GetGiteaEndpointParams struct {
/* Name.
The name of the Gitea endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the get gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGiteaEndpointParams) WithDefaults() *GetGiteaEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the get gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGiteaEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the get gitea endpoint params
func (o *GetGiteaEndpointParams) WithTimeout(timeout time.Duration) *GetGiteaEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get gitea endpoint params
func (o *GetGiteaEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get gitea endpoint params
func (o *GetGiteaEndpointParams) WithContext(ctx context.Context) *GetGiteaEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get gitea endpoint params
func (o *GetGiteaEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get gitea endpoint params
func (o *GetGiteaEndpointParams) WithHTTPClient(client *http.Client) *GetGiteaEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get gitea endpoint params
func (o *GetGiteaEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithName adds the name to the get gitea endpoint params
func (o *GetGiteaEndpointParams) WithName(name string) *GetGiteaEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the get gitea endpoint params
func (o *GetGiteaEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *GetGiteaEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// GetGiteaEndpointReader is a Reader for the GetGiteaEndpoint structure.
type GetGiteaEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetGiteaEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetGiteaEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewGetGiteaEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewGetGiteaEndpointOK creates a GetGiteaEndpointOK with default headers values
func NewGetGiteaEndpointOK() *GetGiteaEndpointOK {
return &GetGiteaEndpointOK{}
}
/*
GetGiteaEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type GetGiteaEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this get gitea endpoint o k response has a 2xx status code
func (o *GetGiteaEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this get gitea endpoint o k response has a 3xx status code
func (o *GetGiteaEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this get gitea endpoint o k response has a 4xx status code
func (o *GetGiteaEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this get gitea endpoint o k response has a 5xx status code
func (o *GetGiteaEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this get gitea endpoint o k response a status code equal to that given
func (o *GetGiteaEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the get gitea endpoint o k response
func (o *GetGiteaEndpointOK) Code() int {
return 200
}
func (o *GetGiteaEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints/{name}][%d] getGiteaEndpointOK %s", 200, payload)
}
func (o *GetGiteaEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints/{name}][%d] getGiteaEndpointOK %s", 200, payload)
}
func (o *GetGiteaEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *GetGiteaEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetGiteaEndpointDefault creates a GetGiteaEndpointDefault with default headers values
func NewGetGiteaEndpointDefault(code int) *GetGiteaEndpointDefault {
return &GetGiteaEndpointDefault{
_statusCode: code,
}
}
/*
GetGiteaEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type GetGiteaEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this get gitea endpoint default response has a 2xx status code
func (o *GetGiteaEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this get gitea endpoint default response has a 3xx status code
func (o *GetGiteaEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this get gitea endpoint default response has a 4xx status code
func (o *GetGiteaEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this get gitea endpoint default response has a 5xx status code
func (o *GetGiteaEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this get gitea endpoint default response a status code equal to that given
func (o *GetGiteaEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the get gitea endpoint default response
func (o *GetGiteaEndpointDefault) Code() int {
return o._statusCode
}
func (o *GetGiteaEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints/{name}][%d] GetGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *GetGiteaEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints/{name}][%d] GetGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *GetGiteaEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *GetGiteaEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,151 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewGetGithubEndpointParams creates a new GetGithubEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewGetGithubEndpointParams() *GetGithubEndpointParams {
return &GetGithubEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetGithubEndpointParamsWithTimeout creates a new GetGithubEndpointParams object
// with the ability to set a timeout on a request.
func NewGetGithubEndpointParamsWithTimeout(timeout time.Duration) *GetGithubEndpointParams {
return &GetGithubEndpointParams{
timeout: timeout,
}
}
// NewGetGithubEndpointParamsWithContext creates a new GetGithubEndpointParams object
// with the ability to set a context for a request.
func NewGetGithubEndpointParamsWithContext(ctx context.Context) *GetGithubEndpointParams {
return &GetGithubEndpointParams{
Context: ctx,
}
}
// NewGetGithubEndpointParamsWithHTTPClient creates a new GetGithubEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewGetGithubEndpointParamsWithHTTPClient(client *http.Client) *GetGithubEndpointParams {
return &GetGithubEndpointParams{
HTTPClient: client,
}
}
/*
GetGithubEndpointParams contains all the parameters to send to the API endpoint
for the get github endpoint operation.
Typically these are written to a http.Request.
*/
type GetGithubEndpointParams struct {
/* Name.
The name of the GitHub endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the get github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGithubEndpointParams) WithDefaults() *GetGithubEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the get github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *GetGithubEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the get github endpoint params
func (o *GetGithubEndpointParams) WithTimeout(timeout time.Duration) *GetGithubEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get github endpoint params
func (o *GetGithubEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get github endpoint params
func (o *GetGithubEndpointParams) WithContext(ctx context.Context) *GetGithubEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get github endpoint params
func (o *GetGithubEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get github endpoint params
func (o *GetGithubEndpointParams) WithHTTPClient(client *http.Client) *GetGithubEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get github endpoint params
func (o *GetGithubEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithName adds the name to the get github endpoint params
func (o *GetGithubEndpointParams) WithName(name string) *GetGithubEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the get github endpoint params
func (o *GetGithubEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *GetGithubEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// GetGithubEndpointReader is a Reader for the GetGithubEndpoint structure.
type GetGithubEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetGithubEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetGithubEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewGetGithubEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewGetGithubEndpointOK creates a GetGithubEndpointOK with default headers values
func NewGetGithubEndpointOK() *GetGithubEndpointOK {
return &GetGithubEndpointOK{}
}
/*
GetGithubEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type GetGithubEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this get github endpoint o k response has a 2xx status code
func (o *GetGithubEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this get github endpoint o k response has a 3xx status code
func (o *GetGithubEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this get github endpoint o k response has a 4xx status code
func (o *GetGithubEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this get github endpoint o k response has a 5xx status code
func (o *GetGithubEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this get github endpoint o k response a status code equal to that given
func (o *GetGithubEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the get github endpoint o k response
func (o *GetGithubEndpointOK) Code() int {
return 200
}
func (o *GetGithubEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints/{name}][%d] getGithubEndpointOK %s", 200, payload)
}
func (o *GetGithubEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints/{name}][%d] getGithubEndpointOK %s", 200, payload)
}
func (o *GetGithubEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *GetGithubEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetGithubEndpointDefault creates a GetGithubEndpointDefault with default headers values
func NewGetGithubEndpointDefault(code int) *GetGithubEndpointDefault {
return &GetGithubEndpointDefault{
_statusCode: code,
}
}
/*
GetGithubEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type GetGithubEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this get github endpoint default response has a 2xx status code
func (o *GetGithubEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this get github endpoint default response has a 3xx status code
func (o *GetGithubEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this get github endpoint default response has a 4xx status code
func (o *GetGithubEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this get github endpoint default response has a 5xx status code
func (o *GetGithubEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this get github endpoint default response a status code equal to that given
func (o *GetGithubEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the get github endpoint default response
func (o *GetGithubEndpointDefault) Code() int {
return o._statusCode
}
func (o *GetGithubEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints/{name}][%d] GetGithubEndpoint default %s", o._statusCode, payload)
}
func (o *GetGithubEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints/{name}][%d] GetGithubEndpoint default %s", o._statusCode, payload)
}
func (o *GetGithubEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *GetGithubEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,128 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewListGiteaEndpointsParams creates a new ListGiteaEndpointsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewListGiteaEndpointsParams() *ListGiteaEndpointsParams {
return &ListGiteaEndpointsParams{
timeout: cr.DefaultTimeout,
}
}
// NewListGiteaEndpointsParamsWithTimeout creates a new ListGiteaEndpointsParams object
// with the ability to set a timeout on a request.
func NewListGiteaEndpointsParamsWithTimeout(timeout time.Duration) *ListGiteaEndpointsParams {
return &ListGiteaEndpointsParams{
timeout: timeout,
}
}
// NewListGiteaEndpointsParamsWithContext creates a new ListGiteaEndpointsParams object
// with the ability to set a context for a request.
func NewListGiteaEndpointsParamsWithContext(ctx context.Context) *ListGiteaEndpointsParams {
return &ListGiteaEndpointsParams{
Context: ctx,
}
}
// NewListGiteaEndpointsParamsWithHTTPClient creates a new ListGiteaEndpointsParams object
// with the ability to set a custom HTTPClient for a request.
func NewListGiteaEndpointsParamsWithHTTPClient(client *http.Client) *ListGiteaEndpointsParams {
return &ListGiteaEndpointsParams{
HTTPClient: client,
}
}
/*
ListGiteaEndpointsParams contains all the parameters to send to the API endpoint
for the list gitea endpoints operation.
Typically these are written to a http.Request.
*/
type ListGiteaEndpointsParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the list gitea endpoints params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGiteaEndpointsParams) WithDefaults() *ListGiteaEndpointsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the list gitea endpoints params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGiteaEndpointsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) WithTimeout(timeout time.Duration) *ListGiteaEndpointsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) WithContext(ctx context.Context) *ListGiteaEndpointsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) WithHTTPClient(client *http.Client) *ListGiteaEndpointsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the list gitea endpoints params
func (o *ListGiteaEndpointsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *ListGiteaEndpointsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// ListGiteaEndpointsReader is a Reader for the ListGiteaEndpoints structure.
type ListGiteaEndpointsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ListGiteaEndpointsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewListGiteaEndpointsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewListGiteaEndpointsDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewListGiteaEndpointsOK creates a ListGiteaEndpointsOK with default headers values
func NewListGiteaEndpointsOK() *ListGiteaEndpointsOK {
return &ListGiteaEndpointsOK{}
}
/*
ListGiteaEndpointsOK describes a response with status code 200, with default header values.
ForgeEndpoints
*/
type ListGiteaEndpointsOK struct {
Payload garm_params.ForgeEndpoints
}
// IsSuccess returns true when this list gitea endpoints o k response has a 2xx status code
func (o *ListGiteaEndpointsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this list gitea endpoints o k response has a 3xx status code
func (o *ListGiteaEndpointsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this list gitea endpoints o k response has a 4xx status code
func (o *ListGiteaEndpointsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this list gitea endpoints o k response has a 5xx status code
func (o *ListGiteaEndpointsOK) IsServerError() bool {
return false
}
// IsCode returns true when this list gitea endpoints o k response a status code equal to that given
func (o *ListGiteaEndpointsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the list gitea endpoints o k response
func (o *ListGiteaEndpointsOK) Code() int {
return 200
}
func (o *ListGiteaEndpointsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints][%d] listGiteaEndpointsOK %s", 200, payload)
}
func (o *ListGiteaEndpointsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints][%d] listGiteaEndpointsOK %s", 200, payload)
}
func (o *ListGiteaEndpointsOK) GetPayload() garm_params.ForgeEndpoints {
return o.Payload
}
func (o *ListGiteaEndpointsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewListGiteaEndpointsDefault creates a ListGiteaEndpointsDefault with default headers values
func NewListGiteaEndpointsDefault(code int) *ListGiteaEndpointsDefault {
return &ListGiteaEndpointsDefault{
_statusCode: code,
}
}
/*
ListGiteaEndpointsDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type ListGiteaEndpointsDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this list gitea endpoints default response has a 2xx status code
func (o *ListGiteaEndpointsDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this list gitea endpoints default response has a 3xx status code
func (o *ListGiteaEndpointsDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this list gitea endpoints default response has a 4xx status code
func (o *ListGiteaEndpointsDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this list gitea endpoints default response has a 5xx status code
func (o *ListGiteaEndpointsDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this list gitea endpoints default response a status code equal to that given
func (o *ListGiteaEndpointsDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the list gitea endpoints default response
func (o *ListGiteaEndpointsDefault) Code() int {
return o._statusCode
}
func (o *ListGiteaEndpointsDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints][%d] ListGiteaEndpoints default %s", o._statusCode, payload)
}
func (o *ListGiteaEndpointsDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /gitea/endpoints][%d] ListGiteaEndpoints default %s", o._statusCode, payload)
}
func (o *ListGiteaEndpointsDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *ListGiteaEndpointsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,128 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewListGithubEndpointsParams creates a new ListGithubEndpointsParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewListGithubEndpointsParams() *ListGithubEndpointsParams {
return &ListGithubEndpointsParams{
timeout: cr.DefaultTimeout,
}
}
// NewListGithubEndpointsParamsWithTimeout creates a new ListGithubEndpointsParams object
// with the ability to set a timeout on a request.
func NewListGithubEndpointsParamsWithTimeout(timeout time.Duration) *ListGithubEndpointsParams {
return &ListGithubEndpointsParams{
timeout: timeout,
}
}
// NewListGithubEndpointsParamsWithContext creates a new ListGithubEndpointsParams object
// with the ability to set a context for a request.
func NewListGithubEndpointsParamsWithContext(ctx context.Context) *ListGithubEndpointsParams {
return &ListGithubEndpointsParams{
Context: ctx,
}
}
// NewListGithubEndpointsParamsWithHTTPClient creates a new ListGithubEndpointsParams object
// with the ability to set a custom HTTPClient for a request.
func NewListGithubEndpointsParamsWithHTTPClient(client *http.Client) *ListGithubEndpointsParams {
return &ListGithubEndpointsParams{
HTTPClient: client,
}
}
/*
ListGithubEndpointsParams contains all the parameters to send to the API endpoint
for the list github endpoints operation.
Typically these are written to a http.Request.
*/
type ListGithubEndpointsParams struct {
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the list github endpoints params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGithubEndpointsParams) WithDefaults() *ListGithubEndpointsParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the list github endpoints params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListGithubEndpointsParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the list github endpoints params
func (o *ListGithubEndpointsParams) WithTimeout(timeout time.Duration) *ListGithubEndpointsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the list github endpoints params
func (o *ListGithubEndpointsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the list github endpoints params
func (o *ListGithubEndpointsParams) WithContext(ctx context.Context) *ListGithubEndpointsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the list github endpoints params
func (o *ListGithubEndpointsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the list github endpoints params
func (o *ListGithubEndpointsParams) WithHTTPClient(client *http.Client) *ListGithubEndpointsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the list github endpoints params
func (o *ListGithubEndpointsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WriteToRequest writes these params to a swagger request
func (o *ListGithubEndpointsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// ListGithubEndpointsReader is a Reader for the ListGithubEndpoints structure.
type ListGithubEndpointsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ListGithubEndpointsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewListGithubEndpointsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewListGithubEndpointsDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewListGithubEndpointsOK creates a ListGithubEndpointsOK with default headers values
func NewListGithubEndpointsOK() *ListGithubEndpointsOK {
return &ListGithubEndpointsOK{}
}
/*
ListGithubEndpointsOK describes a response with status code 200, with default header values.
ForgeEndpoints
*/
type ListGithubEndpointsOK struct {
Payload garm_params.ForgeEndpoints
}
// IsSuccess returns true when this list github endpoints o k response has a 2xx status code
func (o *ListGithubEndpointsOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this list github endpoints o k response has a 3xx status code
func (o *ListGithubEndpointsOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this list github endpoints o k response has a 4xx status code
func (o *ListGithubEndpointsOK) IsClientError() bool {
return false
}
// IsServerError returns true when this list github endpoints o k response has a 5xx status code
func (o *ListGithubEndpointsOK) IsServerError() bool {
return false
}
// IsCode returns true when this list github endpoints o k response a status code equal to that given
func (o *ListGithubEndpointsOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the list github endpoints o k response
func (o *ListGithubEndpointsOK) Code() int {
return 200
}
func (o *ListGithubEndpointsOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints][%d] listGithubEndpointsOK %s", 200, payload)
}
func (o *ListGithubEndpointsOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints][%d] listGithubEndpointsOK %s", 200, payload)
}
func (o *ListGithubEndpointsOK) GetPayload() garm_params.ForgeEndpoints {
return o.Payload
}
func (o *ListGithubEndpointsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewListGithubEndpointsDefault creates a ListGithubEndpointsDefault with default headers values
func NewListGithubEndpointsDefault(code int) *ListGithubEndpointsDefault {
return &ListGithubEndpointsDefault{
_statusCode: code,
}
}
/*
ListGithubEndpointsDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type ListGithubEndpointsDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this list github endpoints default response has a 2xx status code
func (o *ListGithubEndpointsDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this list github endpoints default response has a 3xx status code
func (o *ListGithubEndpointsDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this list github endpoints default response has a 4xx status code
func (o *ListGithubEndpointsDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this list github endpoints default response has a 5xx status code
func (o *ListGithubEndpointsDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this list github endpoints default response a status code equal to that given
func (o *ListGithubEndpointsDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the list github endpoints default response
func (o *ListGithubEndpointsDefault) Code() int {
return o._statusCode
}
func (o *ListGithubEndpointsDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints][%d] ListGithubEndpoints default %s", o._statusCode, payload)
}
func (o *ListGithubEndpointsDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /github/endpoints][%d] ListGithubEndpoints default %s", o._statusCode, payload)
}
func (o *ListGithubEndpointsDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *ListGithubEndpointsDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,173 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewUpdateGiteaEndpointParams creates a new UpdateGiteaEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewUpdateGiteaEndpointParams() *UpdateGiteaEndpointParams {
return &UpdateGiteaEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewUpdateGiteaEndpointParamsWithTimeout creates a new UpdateGiteaEndpointParams object
// with the ability to set a timeout on a request.
func NewUpdateGiteaEndpointParamsWithTimeout(timeout time.Duration) *UpdateGiteaEndpointParams {
return &UpdateGiteaEndpointParams{
timeout: timeout,
}
}
// NewUpdateGiteaEndpointParamsWithContext creates a new UpdateGiteaEndpointParams object
// with the ability to set a context for a request.
func NewUpdateGiteaEndpointParamsWithContext(ctx context.Context) *UpdateGiteaEndpointParams {
return &UpdateGiteaEndpointParams{
Context: ctx,
}
}
// NewUpdateGiteaEndpointParamsWithHTTPClient creates a new UpdateGiteaEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewUpdateGiteaEndpointParamsWithHTTPClient(client *http.Client) *UpdateGiteaEndpointParams {
return &UpdateGiteaEndpointParams{
HTTPClient: client,
}
}
/*
UpdateGiteaEndpointParams contains all the parameters to send to the API endpoint
for the update gitea endpoint operation.
Typically these are written to a http.Request.
*/
type UpdateGiteaEndpointParams struct {
/* Body.
Parameters used when updating a Gitea endpoint.
*/
Body garm_params.UpdateGiteaEndpointParams
/* Name.
The name of the Gitea endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the update gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGiteaEndpointParams) WithDefaults() *UpdateGiteaEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the update gitea endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGiteaEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) WithTimeout(timeout time.Duration) *UpdateGiteaEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) WithContext(ctx context.Context) *UpdateGiteaEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) WithHTTPClient(client *http.Client) *UpdateGiteaEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) WithBody(body garm_params.UpdateGiteaEndpointParams) *UpdateGiteaEndpointParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) SetBody(body garm_params.UpdateGiteaEndpointParams) {
o.Body = body
}
// WithName adds the name to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) WithName(name string) *UpdateGiteaEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the update gitea endpoint params
func (o *UpdateGiteaEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *UpdateGiteaEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// UpdateGiteaEndpointReader is a Reader for the UpdateGiteaEndpoint structure.
type UpdateGiteaEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *UpdateGiteaEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewUpdateGiteaEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewUpdateGiteaEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewUpdateGiteaEndpointOK creates a UpdateGiteaEndpointOK with default headers values
func NewUpdateGiteaEndpointOK() *UpdateGiteaEndpointOK {
return &UpdateGiteaEndpointOK{}
}
/*
UpdateGiteaEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type UpdateGiteaEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this update gitea endpoint o k response has a 2xx status code
func (o *UpdateGiteaEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this update gitea endpoint o k response has a 3xx status code
func (o *UpdateGiteaEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this update gitea endpoint o k response has a 4xx status code
func (o *UpdateGiteaEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this update gitea endpoint o k response has a 5xx status code
func (o *UpdateGiteaEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this update gitea endpoint o k response a status code equal to that given
func (o *UpdateGiteaEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the update gitea endpoint o k response
func (o *UpdateGiteaEndpointOK) Code() int {
return 200
}
func (o *UpdateGiteaEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/endpoints/{name}][%d] updateGiteaEndpointOK %s", 200, payload)
}
func (o *UpdateGiteaEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/endpoints/{name}][%d] updateGiteaEndpointOK %s", 200, payload)
}
func (o *UpdateGiteaEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *UpdateGiteaEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewUpdateGiteaEndpointDefault creates a UpdateGiteaEndpointDefault with default headers values
func NewUpdateGiteaEndpointDefault(code int) *UpdateGiteaEndpointDefault {
return &UpdateGiteaEndpointDefault{
_statusCode: code,
}
}
/*
UpdateGiteaEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type UpdateGiteaEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this update gitea endpoint default response has a 2xx status code
func (o *UpdateGiteaEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this update gitea endpoint default response has a 3xx status code
func (o *UpdateGiteaEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this update gitea endpoint default response has a 4xx status code
func (o *UpdateGiteaEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this update gitea endpoint default response has a 5xx status code
func (o *UpdateGiteaEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this update gitea endpoint default response a status code equal to that given
func (o *UpdateGiteaEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the update gitea endpoint default response
func (o *UpdateGiteaEndpointDefault) Code() int {
return o._statusCode
}
func (o *UpdateGiteaEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/endpoints/{name}][%d] UpdateGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *UpdateGiteaEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /gitea/endpoints/{name}][%d] UpdateGiteaEndpoint default %s", o._statusCode, payload)
}
func (o *UpdateGiteaEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *UpdateGiteaEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -0,0 +1,173 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewUpdateGithubEndpointParams creates a new UpdateGithubEndpointParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewUpdateGithubEndpointParams() *UpdateGithubEndpointParams {
return &UpdateGithubEndpointParams{
timeout: cr.DefaultTimeout,
}
}
// NewUpdateGithubEndpointParamsWithTimeout creates a new UpdateGithubEndpointParams object
// with the ability to set a timeout on a request.
func NewUpdateGithubEndpointParamsWithTimeout(timeout time.Duration) *UpdateGithubEndpointParams {
return &UpdateGithubEndpointParams{
timeout: timeout,
}
}
// NewUpdateGithubEndpointParamsWithContext creates a new UpdateGithubEndpointParams object
// with the ability to set a context for a request.
func NewUpdateGithubEndpointParamsWithContext(ctx context.Context) *UpdateGithubEndpointParams {
return &UpdateGithubEndpointParams{
Context: ctx,
}
}
// NewUpdateGithubEndpointParamsWithHTTPClient creates a new UpdateGithubEndpointParams object
// with the ability to set a custom HTTPClient for a request.
func NewUpdateGithubEndpointParamsWithHTTPClient(client *http.Client) *UpdateGithubEndpointParams {
return &UpdateGithubEndpointParams{
HTTPClient: client,
}
}
/*
UpdateGithubEndpointParams contains all the parameters to send to the API endpoint
for the update github endpoint operation.
Typically these are written to a http.Request.
*/
type UpdateGithubEndpointParams struct {
/* Body.
Parameters used when updating a GitHub endpoint.
*/
Body garm_params.UpdateGithubEndpointParams
/* Name.
The name of the GitHub endpoint.
*/
Name string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the update github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGithubEndpointParams) WithDefaults() *UpdateGithubEndpointParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the update github endpoint params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *UpdateGithubEndpointParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the update github endpoint params
func (o *UpdateGithubEndpointParams) WithTimeout(timeout time.Duration) *UpdateGithubEndpointParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the update github endpoint params
func (o *UpdateGithubEndpointParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the update github endpoint params
func (o *UpdateGithubEndpointParams) WithContext(ctx context.Context) *UpdateGithubEndpointParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the update github endpoint params
func (o *UpdateGithubEndpointParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the update github endpoint params
func (o *UpdateGithubEndpointParams) WithHTTPClient(client *http.Client) *UpdateGithubEndpointParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the update github endpoint params
func (o *UpdateGithubEndpointParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the update github endpoint params
func (o *UpdateGithubEndpointParams) WithBody(body garm_params.UpdateGithubEndpointParams) *UpdateGithubEndpointParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the update github endpoint params
func (o *UpdateGithubEndpointParams) SetBody(body garm_params.UpdateGithubEndpointParams) {
o.Body = body
}
// WithName adds the name to the update github endpoint params
func (o *UpdateGithubEndpointParams) WithName(name string) *UpdateGithubEndpointParams {
o.SetName(name)
return o
}
// SetName adds the name to the update github endpoint params
func (o *UpdateGithubEndpointParams) SetName(name string) {
o.Name = name
}
// WriteToRequest writes these params to a swagger request
func (o *UpdateGithubEndpointParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
// path param name
if err := r.SetPathParam("name", o.Name); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package endpoints
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// UpdateGithubEndpointReader is a Reader for the UpdateGithubEndpoint structure.
type UpdateGithubEndpointReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *UpdateGithubEndpointReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewUpdateGithubEndpointOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewUpdateGithubEndpointDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewUpdateGithubEndpointOK creates a UpdateGithubEndpointOK with default headers values
func NewUpdateGithubEndpointOK() *UpdateGithubEndpointOK {
return &UpdateGithubEndpointOK{}
}
/*
UpdateGithubEndpointOK describes a response with status code 200, with default header values.
ForgeEndpoint
*/
type UpdateGithubEndpointOK struct {
Payload garm_params.ForgeEndpoint
}
// IsSuccess returns true when this update github endpoint o k response has a 2xx status code
func (o *UpdateGithubEndpointOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this update github endpoint o k response has a 3xx status code
func (o *UpdateGithubEndpointOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this update github endpoint o k response has a 4xx status code
func (o *UpdateGithubEndpointOK) IsClientError() bool {
return false
}
// IsServerError returns true when this update github endpoint o k response has a 5xx status code
func (o *UpdateGithubEndpointOK) IsServerError() bool {
return false
}
// IsCode returns true when this update github endpoint o k response a status code equal to that given
func (o *UpdateGithubEndpointOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the update github endpoint o k response
func (o *UpdateGithubEndpointOK) Code() int {
return 200
}
func (o *UpdateGithubEndpointOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/endpoints/{name}][%d] updateGithubEndpointOK %s", 200, payload)
}
func (o *UpdateGithubEndpointOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/endpoints/{name}][%d] updateGithubEndpointOK %s", 200, payload)
}
func (o *UpdateGithubEndpointOK) GetPayload() garm_params.ForgeEndpoint {
return o.Payload
}
func (o *UpdateGithubEndpointOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewUpdateGithubEndpointDefault creates a UpdateGithubEndpointDefault with default headers values
func NewUpdateGithubEndpointDefault(code int) *UpdateGithubEndpointDefault {
return &UpdateGithubEndpointDefault{
_statusCode: code,
}
}
/*
UpdateGithubEndpointDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type UpdateGithubEndpointDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this update github endpoint default response has a 2xx status code
func (o *UpdateGithubEndpointDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this update github endpoint default response has a 3xx status code
func (o *UpdateGithubEndpointDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this update github endpoint default response has a 4xx status code
func (o *UpdateGithubEndpointDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this update github endpoint default response has a 5xx status code
func (o *UpdateGithubEndpointDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this update github endpoint default response a status code equal to that given
func (o *UpdateGithubEndpointDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the update github endpoint default response
func (o *UpdateGithubEndpointDefault) Code() int {
return o._statusCode
}
func (o *UpdateGithubEndpointDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/endpoints/{name}][%d] UpdateGithubEndpoint default %s", o._statusCode, payload)
}
func (o *UpdateGithubEndpointDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PUT /github/endpoints/{name}][%d] UpdateGithubEndpoint default %s", o._statusCode, payload)
}
func (o *UpdateGithubEndpointDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *UpdateGithubEndpointDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -87,11 +88,13 @@ func (o *CreateEnterprisePoolOK) Code() int {
}
func (o *CreateEnterprisePoolOK) Error() string {
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] createEnterprisePoolOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] createEnterprisePoolOK %s", 200, payload)
}
func (o *CreateEnterprisePoolOK) String() string {
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] createEnterprisePoolOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] createEnterprisePoolOK %s", 200, payload)
}
func (o *CreateEnterprisePoolOK) GetPayload() garm_params.Pool {
@ -157,11 +160,13 @@ func (o *CreateEnterprisePoolDefault) Code() int {
}
func (o *CreateEnterprisePoolDefault) Error() string {
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] CreateEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] CreateEnterprisePool default %s", o._statusCode, payload)
}
func (o *CreateEnterprisePoolDefault) String() string {
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] CreateEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/pools][%d] CreateEnterprisePool default %s", o._statusCode, payload)
}
func (o *CreateEnterprisePoolDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -87,11 +88,13 @@ func (o *CreateEnterpriseOK) Code() int {
}
func (o *CreateEnterpriseOK) Error() string {
return fmt.Sprintf("[POST /enterprises][%d] createEnterpriseOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises][%d] createEnterpriseOK %s", 200, payload)
}
func (o *CreateEnterpriseOK) String() string {
return fmt.Sprintf("[POST /enterprises][%d] createEnterpriseOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises][%d] createEnterpriseOK %s", 200, payload)
}
func (o *CreateEnterpriseOK) GetPayload() garm_params.Enterprise {
@ -157,11 +160,13 @@ func (o *CreateEnterpriseDefault) Code() int {
}
func (o *CreateEnterpriseDefault) Error() string {
return fmt.Sprintf("[POST /enterprises][%d] CreateEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises][%d] CreateEnterprise default %s", o._statusCode, payload)
}
func (o *CreateEnterpriseDefault) String() string {
return fmt.Sprintf("[POST /enterprises][%d] CreateEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises][%d] CreateEnterprise default %s", o._statusCode, payload)
}
func (o *CreateEnterpriseDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -0,0 +1,173 @@
// Code generated by go-swagger; DO NOT EDIT.
package enterprises
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
garm_params "github.com/cloudbase/garm/params"
)
// NewCreateEnterpriseScaleSetParams creates a new CreateEnterpriseScaleSetParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewCreateEnterpriseScaleSetParams() *CreateEnterpriseScaleSetParams {
return &CreateEnterpriseScaleSetParams{
timeout: cr.DefaultTimeout,
}
}
// NewCreateEnterpriseScaleSetParamsWithTimeout creates a new CreateEnterpriseScaleSetParams object
// with the ability to set a timeout on a request.
func NewCreateEnterpriseScaleSetParamsWithTimeout(timeout time.Duration) *CreateEnterpriseScaleSetParams {
return &CreateEnterpriseScaleSetParams{
timeout: timeout,
}
}
// NewCreateEnterpriseScaleSetParamsWithContext creates a new CreateEnterpriseScaleSetParams object
// with the ability to set a context for a request.
func NewCreateEnterpriseScaleSetParamsWithContext(ctx context.Context) *CreateEnterpriseScaleSetParams {
return &CreateEnterpriseScaleSetParams{
Context: ctx,
}
}
// NewCreateEnterpriseScaleSetParamsWithHTTPClient creates a new CreateEnterpriseScaleSetParams object
// with the ability to set a custom HTTPClient for a request.
func NewCreateEnterpriseScaleSetParamsWithHTTPClient(client *http.Client) *CreateEnterpriseScaleSetParams {
return &CreateEnterpriseScaleSetParams{
HTTPClient: client,
}
}
/*
CreateEnterpriseScaleSetParams contains all the parameters to send to the API endpoint
for the create enterprise scale set operation.
Typically these are written to a http.Request.
*/
type CreateEnterpriseScaleSetParams struct {
/* Body.
Parameters used when creating the enterprise scale set.
*/
Body garm_params.CreateScaleSetParams
/* EnterpriseID.
Enterprise ID.
*/
EnterpriseID string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the create enterprise scale set params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateEnterpriseScaleSetParams) WithDefaults() *CreateEnterpriseScaleSetParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the create enterprise scale set params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *CreateEnterpriseScaleSetParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) WithTimeout(timeout time.Duration) *CreateEnterpriseScaleSetParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) WithContext(ctx context.Context) *CreateEnterpriseScaleSetParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) WithHTTPClient(client *http.Client) *CreateEnterpriseScaleSetParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) WithBody(body garm_params.CreateScaleSetParams) *CreateEnterpriseScaleSetParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) SetBody(body garm_params.CreateScaleSetParams) {
o.Body = body
}
// WithEnterpriseID adds the enterpriseID to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) WithEnterpriseID(enterpriseID string) *CreateEnterpriseScaleSetParams {
o.SetEnterpriseID(enterpriseID)
return o
}
// SetEnterpriseID adds the enterpriseId to the create enterprise scale set params
func (o *CreateEnterpriseScaleSetParams) SetEnterpriseID(enterpriseID string) {
o.EnterpriseID = enterpriseID
}
// WriteToRequest writes these params to a swagger request
func (o *CreateEnterpriseScaleSetParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
// path param enterpriseID
if err := r.SetPathParam("enterpriseID", o.EnterpriseID); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,184 @@
// Code generated by go-swagger; DO NOT EDIT.
package enterprises
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
apiserver_params "github.com/cloudbase/garm/apiserver/params"
garm_params "github.com/cloudbase/garm/params"
)
// CreateEnterpriseScaleSetReader is a Reader for the CreateEnterpriseScaleSet structure.
type CreateEnterpriseScaleSetReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *CreateEnterpriseScaleSetReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewCreateEnterpriseScaleSetOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
result := NewCreateEnterpriseScaleSetDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewCreateEnterpriseScaleSetOK creates a CreateEnterpriseScaleSetOK with default headers values
func NewCreateEnterpriseScaleSetOK() *CreateEnterpriseScaleSetOK {
return &CreateEnterpriseScaleSetOK{}
}
/*
CreateEnterpriseScaleSetOK describes a response with status code 200, with default header values.
ScaleSet
*/
type CreateEnterpriseScaleSetOK struct {
Payload garm_params.ScaleSet
}
// IsSuccess returns true when this create enterprise scale set o k response has a 2xx status code
func (o *CreateEnterpriseScaleSetOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this create enterprise scale set o k response has a 3xx status code
func (o *CreateEnterpriseScaleSetOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this create enterprise scale set o k response has a 4xx status code
func (o *CreateEnterpriseScaleSetOK) IsClientError() bool {
return false
}
// IsServerError returns true when this create enterprise scale set o k response has a 5xx status code
func (o *CreateEnterpriseScaleSetOK) IsServerError() bool {
return false
}
// IsCode returns true when this create enterprise scale set o k response a status code equal to that given
func (o *CreateEnterpriseScaleSetOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the create enterprise scale set o k response
func (o *CreateEnterpriseScaleSetOK) Code() int {
return 200
}
func (o *CreateEnterpriseScaleSetOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/scalesets][%d] createEnterpriseScaleSetOK %s", 200, payload)
}
func (o *CreateEnterpriseScaleSetOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/scalesets][%d] createEnterpriseScaleSetOK %s", 200, payload)
}
func (o *CreateEnterpriseScaleSetOK) GetPayload() garm_params.ScaleSet {
return o.Payload
}
func (o *CreateEnterpriseScaleSetOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewCreateEnterpriseScaleSetDefault creates a CreateEnterpriseScaleSetDefault with default headers values
func NewCreateEnterpriseScaleSetDefault(code int) *CreateEnterpriseScaleSetDefault {
return &CreateEnterpriseScaleSetDefault{
_statusCode: code,
}
}
/*
CreateEnterpriseScaleSetDefault describes a response with status code -1, with default header values.
APIErrorResponse
*/
type CreateEnterpriseScaleSetDefault struct {
_statusCode int
Payload apiserver_params.APIErrorResponse
}
// IsSuccess returns true when this create enterprise scale set default response has a 2xx status code
func (o *CreateEnterpriseScaleSetDefault) IsSuccess() bool {
return o._statusCode/100 == 2
}
// IsRedirect returns true when this create enterprise scale set default response has a 3xx status code
func (o *CreateEnterpriseScaleSetDefault) IsRedirect() bool {
return o._statusCode/100 == 3
}
// IsClientError returns true when this create enterprise scale set default response has a 4xx status code
func (o *CreateEnterpriseScaleSetDefault) IsClientError() bool {
return o._statusCode/100 == 4
}
// IsServerError returns true when this create enterprise scale set default response has a 5xx status code
func (o *CreateEnterpriseScaleSetDefault) IsServerError() bool {
return o._statusCode/100 == 5
}
// IsCode returns true when this create enterprise scale set default response a status code equal to that given
func (o *CreateEnterpriseScaleSetDefault) IsCode(code int) bool {
return o._statusCode == code
}
// Code gets the status code for the create enterprise scale set default response
func (o *CreateEnterpriseScaleSetDefault) Code() int {
return o._statusCode
}
func (o *CreateEnterpriseScaleSetDefault) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/scalesets][%d] CreateEnterpriseScaleSet default %s", o._statusCode, payload)
}
func (o *CreateEnterpriseScaleSetDefault) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /enterprises/{enterpriseID}/scalesets][%d] CreateEnterpriseScaleSet default %s", o._statusCode, payload)
}
func (o *CreateEnterpriseScaleSetDefault) GetPayload() apiserver_params.APIErrorResponse {
return o.Payload
}
func (o *CreateEnterpriseScaleSetDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -81,11 +82,13 @@ func (o *DeleteEnterprisePoolDefault) Code() int {
}
func (o *DeleteEnterprisePoolDefault) Error() string {
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}/pools/{poolID}][%d] DeleteEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}/pools/{poolID}][%d] DeleteEnterprisePool default %s", o._statusCode, payload)
}
func (o *DeleteEnterprisePoolDefault) String() string {
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}/pools/{poolID}][%d] DeleteEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}/pools/{poolID}][%d] DeleteEnterprisePool default %s", o._statusCode, payload)
}
func (o *DeleteEnterprisePoolDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -81,11 +82,13 @@ func (o *DeleteEnterpriseDefault) Code() int {
}
func (o *DeleteEnterpriseDefault) Error() string {
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}][%d] DeleteEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}][%d] DeleteEnterprise default %s", o._statusCode, payload)
}
func (o *DeleteEnterpriseDefault) String() string {
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}][%d] DeleteEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[DELETE /enterprises/{enterpriseID}][%d] DeleteEnterprise default %s", o._statusCode, payload)
}
func (o *DeleteEnterpriseDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -7,6 +7,7 @@ package enterprises
import (
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
@ -15,6 +16,31 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientServi
return &Client{transport: transport, formats: formats}
}
// New creates a new enterprises API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new enterprises API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client for enterprises API
*/
@ -23,7 +49,7 @@ type Client struct {
formats strfmt.Registry
}
// ClientOption is the option for Client methods
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
// ClientService is the interface for Client methods
@ -32,6 +58,8 @@ type ClientService interface {
CreateEnterprisePool(params *CreateEnterprisePoolParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateEnterprisePoolOK, error)
CreateEnterpriseScaleSet(params *CreateEnterpriseScaleSetParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateEnterpriseScaleSetOK, error)
DeleteEnterprise(params *DeleteEnterpriseParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
DeleteEnterprisePool(params *DeleteEnterprisePoolParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) error
@ -44,6 +72,8 @@ type ClientService interface {
ListEnterprisePools(params *ListEnterprisePoolsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListEnterprisePoolsOK, error)
ListEnterpriseScaleSets(params *ListEnterpriseScaleSetsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListEnterpriseScaleSetsOK, error)
ListEnterprises(params *ListEnterprisesParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListEnterprisesOK, error)
UpdateEnterprise(params *UpdateEnterpriseParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*UpdateEnterpriseOK, error)
@ -129,6 +159,44 @@ func (a *Client) CreateEnterprisePool(params *CreateEnterprisePoolParams, authIn
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
CreateEnterpriseScaleSet creates enterprise pool with the parameters given
*/
func (a *Client) CreateEnterpriseScaleSet(params *CreateEnterpriseScaleSetParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateEnterpriseScaleSetOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewCreateEnterpriseScaleSetParams()
}
op := &runtime.ClientOperation{
ID: "CreateEnterpriseScaleSet",
Method: "POST",
PathPattern: "/enterprises/{enterpriseID}/scalesets",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &CreateEnterpriseScaleSetReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*CreateEnterpriseScaleSetOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*CreateEnterpriseScaleSetDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
DeleteEnterprise deletes enterprise by ID
*/
@ -345,6 +413,44 @@ func (a *Client) ListEnterprisePools(params *ListEnterprisePoolsParams, authInfo
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
ListEnterpriseScaleSets lists enterprise scale sets
*/
func (a *Client) ListEnterpriseScaleSets(params *ListEnterpriseScaleSetsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListEnterpriseScaleSetsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewListEnterpriseScaleSetsParams()
}
op := &runtime.ClientOperation{
ID: "ListEnterpriseScaleSets",
Method: "GET",
PathPattern: "/enterprises/{enterpriseID}/scalesets",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http"},
Params: params,
Reader: &ListEnterpriseScaleSetsReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ListEnterpriseScaleSetsOK)
if ok {
return success, nil
}
// unexpected success response
unexpectedSuccess := result.(*ListEnterpriseScaleSetsDefault)
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
}
/*
ListEnterprises lists all enterprises
*/

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -87,11 +88,13 @@ func (o *GetEnterprisePoolOK) Code() int {
}
func (o *GetEnterprisePoolOK) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] getEnterprisePoolOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] getEnterprisePoolOK %s", 200, payload)
}
func (o *GetEnterprisePoolOK) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] getEnterprisePoolOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] getEnterprisePoolOK %s", 200, payload)
}
func (o *GetEnterprisePoolOK) GetPayload() garm_params.Pool {
@ -157,11 +160,13 @@ func (o *GetEnterprisePoolDefault) Code() int {
}
func (o *GetEnterprisePoolDefault) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] GetEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] GetEnterprisePool default %s", o._statusCode, payload)
}
func (o *GetEnterprisePoolDefault) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] GetEnterprisePool default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/pools/{poolID}][%d] GetEnterprisePool default %s", o._statusCode, payload)
}
func (o *GetEnterprisePoolDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -87,11 +88,13 @@ func (o *GetEnterpriseOK) Code() int {
}
func (o *GetEnterpriseOK) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] getEnterpriseOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] getEnterpriseOK %s", 200, payload)
}
func (o *GetEnterpriseOK) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] getEnterpriseOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] getEnterpriseOK %s", 200, payload)
}
func (o *GetEnterpriseOK) GetPayload() garm_params.Enterprise {
@ -157,11 +160,13 @@ func (o *GetEnterpriseDefault) Code() int {
}
func (o *GetEnterpriseDefault) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] GetEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] GetEnterprise default %s", o._statusCode, payload)
}
func (o *GetEnterpriseDefault) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] GetEnterprise default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}][%d] GetEnterprise default %s", o._statusCode, payload)
}
func (o *GetEnterpriseDefault) GetPayload() apiserver_params.APIErrorResponse {

View file

@ -6,6 +6,7 @@ package enterprises
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
@ -87,11 +88,13 @@ func (o *ListEnterpriseInstancesOK) Code() int {
}
func (o *ListEnterpriseInstancesOK) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] listEnterpriseInstancesOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] listEnterpriseInstancesOK %s", 200, payload)
}
func (o *ListEnterpriseInstancesOK) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] listEnterpriseInstancesOK %+v", 200, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] listEnterpriseInstancesOK %s", 200, payload)
}
func (o *ListEnterpriseInstancesOK) GetPayload() garm_params.Instances {
@ -157,11 +160,13 @@ func (o *ListEnterpriseInstancesDefault) Code() int {
}
func (o *ListEnterpriseInstancesDefault) Error() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] ListEnterpriseInstances default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] ListEnterpriseInstances default %s", o._statusCode, payload)
}
func (o *ListEnterpriseInstancesDefault) String() string {
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] ListEnterpriseInstances default %+v", o._statusCode, o.Payload)
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /enterprises/{enterpriseID}/instances][%d] ListEnterpriseInstances default %s", o._statusCode, payload)
}
func (o *ListEnterpriseInstancesDefault) GetPayload() apiserver_params.APIErrorResponse {

Some files were not shown because too many files have changed in this diff Show more