{"id":24664481,"url":"https://github.com/doodlescheduling/swagger-hub-controller","last_synced_at":"2026-04-17T06:33:09.693Z","repository":{"id":243050346,"uuid":"811287573","full_name":"DoodleScheduling/swagger-hub-controller","owner":"DoodleScheduling","description":"Kubernetes controller for managing swagger UI","archived":false,"fork":false,"pushed_at":"2026-04-12T01:37:09.000Z","size":984,"stargazers_count":0,"open_issues_count":16,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-12T03:27:19.086Z","etag":null,"topics":["kubernetes-controller","openapi","swagger","swagger-ui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DoodleScheduling.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-06T09:58:37.000Z","updated_at":"2026-04-12T01:36:22.000Z","dependencies_parsed_at":"2024-06-19T03:04:39.507Z","dependency_job_id":"51620125-324c-4cca-a63b-56e02bb0cd33","html_url":"https://github.com/DoodleScheduling/swagger-hub-controller","commit_stats":null,"previous_names":["doodlescheduling/swagger-hub-controller"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/DoodleScheduling/swagger-hub-controller","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoodleScheduling%2Fswagger-hub-controller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoodleScheduling%2Fswagger-hub-controller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoodleScheduling%2Fswagger-hub-controller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoodleScheduling%2Fswagger-hub-controller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DoodleScheduling","download_url":"https://codeload.github.com/DoodleScheduling/swagger-hub-controller/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoodleScheduling%2Fswagger-hub-controller/sbom","scorecard":{"id":316492,"data":{"date":"2025-08-17T22:15:34Z","repo":{"name":"github.com/DoodleScheduling/swagger-hub-controller","commit":"976b996c58c228679dec90b455ae613b928965cd"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":7.8,"checks":[{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: RenovateBot: renovate.json:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/rebase.yaml:16","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scan.yaml:17","Info: found token with 'none' permissions: .github/workflows/main.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-actions.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-build.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-goreleaser.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-label.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-stale.yaml:1","Info: found token with 'none' permissions: .github/workflows/pr-trivy.yaml:1","Info: found token with 'none' permissions: .github/workflows/rebase.yaml:1","Info: found token with 'none' permissions: .github/workflows/release.yaml:1","Info: found token with 'none' permissions: .github/workflows/report-on-vulnerabilities.yaml:1","Info: found token with 'none' permissions: .github/workflows/scan.yaml:1","Info: found token with 'none' permissions: .github/workflows/scorecard.yaml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  35 out of  35 GitHub-owned GitHubAction dependencies pinned","Info:  40 out of  40 third-party GitHubAction dependencies pinned","Info:   1 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yaml:10"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: checksums.txt.sig: https://github.com/DoodleScheduling/swagger-hub-controller/releases/tag/v0.2.0","Info: signed release artifact: checksums.txt.sig: https://github.com/DoodleScheduling/swagger-hub-controller/releases/tag/v0.1.2","Info: signed release artifact: checksums.txt.sig: https://github.com/DoodleScheduling/swagger-hub-controller/releases/tag/v0.1.1","Info: signed release artifact: checksums.txt.sig: https://github.com/DoodleScheduling/swagger-hub-controller/releases/tag/v0.1.0","Info: signed release artifact: checksums.txt.sig: https://github.com/DoodleScheduling/swagger-hub-controller/releases/tag/v0.0.5","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/DoodleScheduling/swagger-hub-controller/releases/212733990","Warn: release artifact v0.1.2 does not have provenance: https://api.github.com/repos/DoodleScheduling/swagger-hub-controller/releases/193513675","Warn: release artifact v0.1.1 does not have provenance: https://api.github.com/repos/DoodleScheduling/swagger-hub-controller/releases/193510611","Warn: release artifact v0.1.0 does not have provenance: https://api.github.com/repos/DoodleScheduling/swagger-hub-controller/releases/193500733","Warn: release artifact v0.0.5 does not have provenance: https://api.github.com/repos/DoodleScheduling/swagger-hub-controller/releases/173053130"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (30) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"Branch-Protection","score":4,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'master'","Warn: 'stale review dismissal' is disabled on branch 'master'","Warn: required approving review count is 1 on branch 'master'","Info: codeowner review is required on branch 'master'","Warn: 'last push approval' is disabled on branch 'master'","Warn: 'up-to-date branches' is disabled on branch 'master'","Info: status check found to merge onto on branch 'master'","Info: PRs are required in order to make changes on branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"Contributors","score":3,"reason":"project has 1 contributing companies or organizations -- score normalized to 3","details":["Info: found contributions from: DoodleScheduling"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"30 out of 30 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-08-18T00:17:35.528Z","repository_id":243050346,"created_at":"2025-08-18T00:17:35.528Z","updated_at":"2025-08-18T00:17:35.528Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31918540,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kubernetes-controller","openapi","swagger","swagger-ui"],"created_at":"2025-01-26T06:13:13.756Z","updated_at":"2026-04-17T06:33:09.674Z","avatar_url":"https://github.com/DoodleScheduling.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Swagger UI kubernetes controller\n\n[![release](https://img.shields.io/github/release/DoodleScheduling/swagger-hub-controller/all.svg)](https://github.com/DoodleScheduling/swagger-hub-controller/releases)\n[![release](https://github.com/doodlescheduling/swagger-hub-controller/actions/workflows/release.yaml/badge.svg)](https://github.com/doodlescheduling/swagger-hub-controller/actions/workflows/release.yaml)\n[![report](https://goreportcard.com/badge/github.com/DoodleScheduling/swagger-hub-controller)](https://goreportcard.com/report/github.com/DoodleScheduling/swagger-hub-controller)\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/DoodleScheduling/swagger-hub-controller/badge)](https://api.securityscorecards.dev/projects/github.com/DoodleScheduling/swagger-hub-controller)\n[![Coverage Status](https://coveralls.io/repos/github/DoodleScheduling/swagger-hub-controller/badge.svg?branch=master)](https://coveralls.io/github/DoodleScheduling/swagger-hub-controller?branch=master)\n[![license](https://img.shields.io/github/license/DoodleScheduling/swagger-hub-controller.svg)](https://github.com/DoodleScheduling/swagger-hub-controller/blob/master/LICENSE)\n\nThis controller manages deployments of [Swagger UI](https://swagger.io/tools/swagger-ui/).\nThe controller can lookup `SwaggerDefinition` references and hook them up with a `SwaggerHub`.\nEach `SwaggerHub` is a managed [Swagger UI](https://swagger.io/tools/swagger-ui/) deployment which includes the related swagger definitions.\n\nThis approach is great for microservices which have their own OpenAPI specs but a unified swagger-ui is wanted.\n\n### Beta API notice\nFor v0.x releases and beta api we try not to break the API specs. However\nin rare cases backports happen to fix major issues.\n\n## Example\n\n```yaml\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerHub\nmetadata:\n  name: default\nspec:\n  definitionSelector:\n    matchLabels: {}\n```\n\nIf no definition selector on the hub is configured no definitions will be included.\n`matchLabels: {}` will include all of them in the same namespace as the hub.\nBy using match labels or expressions it can be configured what definitions should be included in the hub.\n\nSimilar to the `definitionSelector` it is possible to match definitions cross namespace by using `spec.namespaceSelector`. \nBy default a `SwaggerHub` only looks up definitions from the same namespace as the hub but with a namespace selector this behaviour can be changed.\nUsing `namespaceSelector.matchLabels: {}` will lookup definitions across all namespaces.\n\n```yaml\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerDefinition\nmetadata:\n  name: microservice-a\n  namespace: default\n  labels:\n    scope: external-api\nspec:\n  url: https://microservice-a/openapispecs/v1\n---\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerDefinition\nmetadata:\n  name: microservice-b\n  namespace: default\n  labels:\n    scope: external-api\nspec:\n  url: https://microservice-b/swagger-specs\n```\n\n## Deployment template\nIt is possible to define a custom swagger-ui deployment template which the controller will use to spin up the managed deployment.\nIn the following example the deployment receives an additional container called mysidecar. Also resources\nare declared for the `swagger-ui` container.\n\n**Note**: The swagger-ui container is always called swagger-ui. It is possible to patch that container by using said name as in the example bellow.\n\n```yaml\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerHub\nmetadata:\n  name: default\nspec:\n  definitionSelector:\n    matchLabels: {}\n  deploymentTemplate:\n    spec:\n      template:\n        replicas: 3\n        spec:\n          containers:\n          - name: swagger-ui\n            resources:\n              requests:\n                memory: 256Mi\n                cpu: 50m\n              limits:\n                memory: 512Mi\n          - name: random-sidecar\n            image: mysidecar\n```\n\n## Unify specifications\n\nBy utilizing `SwaggerSpecification` resources it is possible to actually merge multiple `SwaggerDefinitions` into one single swagger specification.\nThis is useful to represent a collection of `SwaggerDefinitions` as a single entity.\n\nThe `SwaggerSpecification` needs to know which `SwaggerDefinitions` is should look up by setting a `spec.definitionSelector` just as with the `SwaggerHub`.\nBy default the first server occurrence from the first SwaggerDefinition is used in the new merged specification. However this might not be wanted therefore the OpenAPI servers\nas well as the info specifications can be overwritten just as in the example bellow:\n\n```yaml\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerSpecification\nmetadata:\n  name: my-api\n  namespace: default\nspec:\n  info: \n    title: My API\n  servers:\n  - url: https://api.gateway.net\n    description: example api entrypoint\n  definitionSelector:\n    matchLabels:\n      scope: external-api #Selects all SwaggerDefinitions from above\n---\napiVersion: swagger.infra.doodle.com/v1beta1\nkind: SwaggerHub\nmetadata:\n  name: default\nspec:\n  specificationSelector:\n    matchLabels: {}\n  definitionSelector:\n    matchLabels:\n      scope: other-definitions\n  deploymentTemplate:\n    spec:\n      template:\n        replicas: 3\n        spec:\n          containers:\n          - name: swagger-ui\n            resources:\n              requests:\n                memory: 256Mi\n                cpu: 50m\n              limits:\n                memory: 512Mi\n          - name: random-sidecar\n            image: mysidecar\n```\n\n\n## Suspend/Resume reconciliation\n\nThe reconciliation can be paused by setting `spec.suspend` to `true`:\n \n```\nkubectl patch swaggerhub default-p '{\"spec\":{\"suspend\": true}}' --type=merge\n```\n\n## Observe SwaggerHub reconciliation\n\nA `SwaggerHub` will have all discovered resources populated in `.status.subResourceCatalog`.\nAlso there are two conditions which are useful for observing `Ready` and a temporary one named `Reconciling`\nas long as a reconciliation is in progress.\n\n## Installation\n\n### Helm\n\nPlease see [chart/swagger-hub-controller](https://github.com/DoodleScheduling/swagger-hub-controller/tree/master/chart/swagger-hub-controller) for the helm chart docs.\n\n### Manifests/kustomize\n\nAlternatively you may get the bundled manifests in each release to deploy it using kustomize or use them directly.\n\n## Configuration\nThe controller can be configured using cmd args:\n```\n--concurrent int                            The number of concurrent SwaggerHub reconciles. (default 4)\n--enable-leader-election                    Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.\n--graceful-shutdown-timeout duration        The duration given to the reconciler to finish before forcibly stopping. (default 10m0s)\n--health-addr string                        The address the health endpoint binds to. (default \":9557\")\n--insecure-kubeconfig-exec                  Allow use of the user.exec section in kubeconfigs provided for remote apply.\n--insecure-kubeconfig-tls                   Allow that kubeconfigs provided for remote apply can disable TLS verification.\n--kube-api-burst int                        The maximum burst queries-per-second of requests sent to the Kubernetes API. (default 300)\n--kube-api-qps float32                      The maximum queries-per-second of requests sent to the Kubernetes API. (default 50)\n--leader-election-lease-duration duration   Interval at which non-leader candidates will wait to force acquire leadership (duration string). (default 35s)\n--leader-election-release-on-cancel         Defines if the leader should step down voluntarily on controller manager shutdown. (default true)\n--leader-election-renew-deadline duration   Duration that the leading controller manager will retry refreshing leadership before giving up (duration string). (default 30s)\n--leader-election-retry-period duration     Duration the LeaderElector clients should wait between tries of actions (duration string). (default 5s)\n--log-encoding string                       Log encoding format. Can be 'json' or 'console'. (default \"json\")\n--log-level string                          Log verbosity level. Can be one of 'trace', 'debug', 'info', 'error'. (default \"info\")\n--max-retry-delay duration                  The maximum amount of time for which an object being reconciled will have to wait before a retry. (default 15m0s)\n--metrics-addr string                       The address the metric endpoint binds to. (default \":9556\")\n--min-retry-delay duration                  The minimum amount of time for which an object being reconciled will have to wait before a retry. (default 750ms)\n--watch-all-namespaces                      Watch for resources in all namespaces, if set to false it will only watch the runtime namespace. (default true)\n--watch-label-selector string               Watch for resources with matching labels e.g. 'sharding.fluxcd.io/shard=shard1'.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoodlescheduling%2Fswagger-hub-controller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoodlescheduling%2Fswagger-hub-controller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoodlescheduling%2Fswagger-hub-controller/lists"}