├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .goreleaser.yaml ├── Dockerfile ├── LICENSE ├── README.md ├── cmd ├── root.go ├── serve.go └── version.go ├── config.yaml ├── defaults.yaml ├── forge_api_v3.json ├── go.mod ├── go.sum ├── gorge.service ├── helm ├── README.md └── gorge │ ├── .helmignore │ ├── .pre-commit-config.yaml │ ├── Chart.yaml │ ├── templates │ ├── deployment.yaml │ ├── ingress.yaml │ ├── pvc.yaml │ ├── route.yaml │ ├── service.yaml │ └── serviceaccount.yaml │ ├── values.schema.json │ └── values.yaml ├── internal ├── config │ └── config.go ├── log │ └── zap.go ├── middleware │ ├── auth.go │ ├── proxy.go │ ├── response_wrapper.go │ ├── stats.go │ └── useragent.go ├── model │ └── module_metadata.go ├── utils │ ├── privileges.go │ ├── privileges_windows.go │ └── tilde.go └── v3 │ ├── api │ ├── module.go │ ├── release.go │ ├── search_filter.go │ └── user.go │ ├── backend │ ├── config.go │ ├── filesystem.go │ └── interface.go │ ├── ui │ ├── assets.go │ ├── assets │ │ ├── favicon.ico │ │ ├── htmx.min.js │ │ ├── js │ │ │ └── table-sort.js │ │ ├── logo.png │ │ ├── pico.min.css │ │ ├── style.css │ │ ├── style.scss │ │ └── theme-switcher.js │ ├── components │ │ ├── author.templ │ │ ├── author_templ.go │ │ ├── head.templ │ │ ├── head_templ.go │ │ ├── module.templ │ │ ├── module_templ.go │ │ ├── nav.templ │ │ ├── nav_templ.go │ │ ├── page.templ │ │ ├── page_templ.go │ │ ├── release.templ │ │ ├── release_templ.go │ │ ├── search.templ │ │ ├── search_templ.go │ │ ├── statistics.templ │ │ ├── statistics_templ.go │ │ └── utils.go │ └── handlers.go │ └── utils │ └── path.go ├── logo.png ├── main.go ├── pkg └── gen │ └── v3 │ ├── .openapi-generator-ignore │ ├── .openapi-generator │ ├── FILES │ └── VERSION │ ├── README.md │ ├── api │ └── openapi.yaml │ └── openapi │ ├── api.go │ ├── api_module_operations.go │ ├── api_module_operations_service.go │ ├── api_release_operations.go │ ├── api_release_operations_service.go │ ├── api_search_filter_operations.go │ ├── api_search_filter_operations_service.go │ ├── api_user_operations.go │ ├── api_user_operations_service.go │ ├── error.go │ ├── helpers.go │ ├── impl.go │ ├── logger.go │ ├── model_add_release_request.go │ ├── model_add_search_filter_409_response.go │ ├── model_delete_user_search_filter_403_response.go │ ├── model_deprecation_request.go │ ├── model_deprecation_request_params.go │ ├── model_get_file_400_response.go │ ├── model_get_file_404_response.go │ ├── model_get_modules_200_response.go │ ├── model_get_modules_200_response_pagination.go │ ├── model_get_release_plans_200_response.go │ ├── model_get_release_plans_200_response_pagination.go │ ├── model_get_releases_200_response.go │ ├── model_get_releases_200_response_pagination.go │ ├── model_get_user_search_filters_401_response.go │ ├── model_get_users_200_response.go │ ├── model_get_users_200_response_pagination.go │ ├── model_module.go │ ├── model_module_abbreviated.go │ ├── model_module_current_release.go │ ├── model_module_minimal.go │ ├── model_module_owner.go │ ├── model_module_superseded_by.go │ ├── model_pagination.go │ ├── model_release.go │ ├── model_release_abbreviated.go │ ├── model_release_minimal.go │ ├── model_release_module.go │ ├── model_release_plan.go │ ├── model_release_plan_abbreviated.go │ ├── model_release_plan_plan_metadata.go │ ├── model_release_plan_plan_metadata_docstring.go │ ├── model_release_plan_plan_metadata_docstring_tags_inner.go │ ├── model_release_task.go │ ├── model_search_filter.go │ ├── model_search_filter_response.go │ ├── model_user.go │ ├── model_user_abbreviated.go │ └── routers.go └── renovate.json /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: build 3 | 4 | on: 5 | push: 6 | branches: 7 | - '*' 8 | tags-ignore: 9 | - '*' 10 | pull_request: 11 | types: 12 | - opened 13 | - reopened 14 | 15 | jobs: 16 | goreleaser: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 21 | with: 22 | fetch-depth: 0 23 | - name: Set up Go 24 | uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 25 | with: 26 | go-version: ^1.22 27 | - name: Run GoReleaser 28 | uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6 29 | with: 30 | distribution: goreleaser 31 | version: latest 32 | args: release --snapshot --clean 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release 3 | 4 | on: 5 | push: 6 | tags: 7 | - '*' 8 | 9 | permissions: 10 | contents: write 11 | packages: write 12 | 13 | jobs: 14 | goreleaser: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 19 | with: 20 | fetch-depth: 0 21 | - name: Set up Go 22 | uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5 23 | with: 24 | go-version: ^1.22 25 | - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3 26 | with: 27 | registry: ghcr.io 28 | username: ${{ github.repository_owner }} 29 | password: ${{ secrets.GITHUB_TOKEN }} 30 | - name: Run GoReleaser 31 | uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6 32 | with: 33 | distribution: goreleaser 34 | version: latest 35 | args: release --clean 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | dist/ 3 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 3 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 4 | 5 | version: 2 6 | 7 | before: 8 | hooks: 9 | - go mod tidy 10 | 11 | builds: 12 | - env: 13 | - CGO_ENABLED=0 14 | goos: 15 | - linux 16 | - windows 17 | - darwin 18 | 19 | archives: 20 | - format: tar.gz 21 | # this name template makes the OS and Arch compatible with the results of `uname`. 22 | name_template: >- 23 | {{ .ProjectName }}_ 24 | {{- .Version }}_ 25 | {{- title .Os }}_ 26 | {{- if eq .Arch "amd64" }}x86_64 27 | {{- else if eq .Arch "386" }}i386 28 | {{- else }}{{ .Arch }}{{ end }} 29 | {{- if .Arm }}v{{ .Arm }}{{ end }} 30 | # use zip for windows archives 31 | format_overrides: 32 | - goos: windows 33 | format: zip 34 | 35 | nfpms: 36 | - homepage: https://github.com/dadav/gorge 37 | maintainer: dadav 38 | description: |- 39 | Gorge is a puppet forge implementation in go. 40 | license: Apache 2.0 41 | formats: 42 | - apk 43 | - deb 44 | - rpm 45 | - termux.deb 46 | - archlinux 47 | provides: 48 | - gorge 49 | contents: 50 | - src: gorge.service 51 | dst: /usr/lib/systemd/system/gorge.service 52 | - src: defaults.yaml 53 | dst: /etc/gorge.yaml 54 | type: "config|noreplace" 55 | 56 | dockers: 57 | - goos: linux 58 | goarch: amd64 59 | image_templates: 60 | - 'ghcr.io/dadav/gorge:{{ .Tag }}' 61 | - 'ghcr.io/dadav/gorge:latest' 62 | build_flag_templates: 63 | - "--label=org.opencontainers.image.created={{.Date}}" 64 | - "--label=org.opencontainers.image.authors=dadav" 65 | - "--label=org.opencontainers.image.url=https://github.com/dadav/gorge" 66 | - "--label=org.opencontainers.image.title={{.ProjectName}}" 67 | - "--label=org.opencontainers.image.revision={{.FullCommit}}" 68 | - "--label=org.opencontainers.image.version={{.Version}}" 69 | 70 | changelog: 71 | sort: asc 72 | filters: 73 | exclude: 74 | - '^docs:' 75 | - '^test:' 76 | - '^chore:' 77 | - '^Merge' 78 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.21@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c 2 | 3 | # Create non-root user and set up permissions in a single layer 4 | RUN adduser -k /dev/null -u 10001 -D gorge \ 5 | && chgrp 0 /home/gorge \ 6 | && chmod -R g+rwX /home/gorge 7 | 8 | # Copy application binary with explicit permissions 9 | COPY --chmod=755 gorge / 10 | 11 | # Set working directory 12 | WORKDIR /home/gorge 13 | 14 | # Switch to non-root user 15 | USER 10001 16 | 17 | # Define volume 18 | VOLUME [ "/home/gorge" ] 19 | 20 | # Set health check 21 | HEALTHCHECK --interval=30s --timeout=3s \ 22 | CMD curl -f http://localhost:8080/readyz || exit 1 23 | 24 | ENTRYPOINT ["/gorge"] 25 | CMD [ "serve" ] 26 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2024 dadav 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package cmd 17 | 18 | import ( 19 | "fmt" 20 | "log" 21 | "path/filepath" 22 | "strings" 23 | 24 | "github.com/spf13/cobra" 25 | "github.com/spf13/pflag" 26 | 27 | homedir "github.com/mitchellh/go-homedir" 28 | "github.com/spf13/viper" 29 | ) 30 | 31 | var cfgFile string 32 | 33 | const envPrefix = "GORGE" 34 | 35 | // rootCmd represents the base command when called without any subcommands 36 | var rootCmd = &cobra.Command{ 37 | Use: "gorge", 38 | Short: "Gorge runs a puppet forge server", 39 | Long: `You can run this tool to provide access to your puppet modules.`, 40 | PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 41 | // You can bind cobra and viper in a few locations, but PersistencePreRunE on the root command works well 42 | return initConfig(cmd) 43 | }, 44 | } 45 | 46 | // Execute adds all child commands to the root command and sets flags appropriately. 47 | // This is called by main.main(). It only needs to happen once to the rootCmd. 48 | func Execute() { 49 | if err := rootCmd.Execute(); err != nil { 50 | log.Fatalf("Error executing root command: %v", err) 51 | } 52 | } 53 | 54 | func init() { 55 | rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gorge.yaml)") 56 | } 57 | 58 | // initConfig reads in config file and ENV variables if set. 59 | func initConfig(cmd *cobra.Command) error { 60 | v := viper.New() 61 | 62 | if cfgFile != "" { 63 | // Use config file from the flag. 64 | v.SetConfigFile(cfgFile) 65 | } else { 66 | home, err := homedir.Dir() 67 | if err != nil { 68 | return fmt.Errorf("failed to get home directory: %w", err) 69 | } 70 | 71 | homeConfig := filepath.Join(home, ".config") 72 | 73 | // Search config in home directory with name ".gorge" (without extension). 74 | v.AddConfigPath(homeConfig) 75 | v.AddConfigPath(".") 76 | v.SetConfigName("gorge") 77 | v.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) 78 | v.SetEnvPrefix(envPrefix) 79 | } 80 | 81 | v.AutomaticEnv() 82 | 83 | // If a config file is found, read it in. 84 | if err := v.ReadInConfig(); err != nil { 85 | if _, ok := err.(viper.ConfigFileNotFoundError); !ok { 86 | // Only return an error if it's not a missing config file 87 | return fmt.Errorf("failed to read config file: %w", err) 88 | } 89 | } else { 90 | log.Printf("Using config file: %s", v.ConfigFileUsed()) 91 | } 92 | 93 | return bindFlags(cmd, v) 94 | } 95 | 96 | // bindFlags binds cobra flags with viper config 97 | func bindFlags(cmd *cobra.Command, v *viper.Viper) error { 98 | var bindingErrors []string 99 | 100 | cmd.Flags().VisitAll(func(f *pflag.Flag) { 101 | configName := f.Name 102 | if !f.Changed && v.IsSet(configName) { 103 | val := v.Get(configName) 104 | if err := cmd.Flags().Set(f.Name, fmt.Sprintf("%v", val)); err != nil { 105 | bindingErrors = append(bindingErrors, fmt.Sprintf("failed to bind flag %s: %v", f.Name, err)) 106 | } 107 | } 108 | }) 109 | 110 | if len(bindingErrors) > 0 { 111 | return fmt.Errorf("flag binding errors: %s", strings.Join(bindingErrors, "; ")) 112 | } 113 | return nil 114 | } 115 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2024 dadav 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package cmd 17 | 18 | import ( 19 | "fmt" 20 | "os" 21 | 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | var version string = "0.7.0" 26 | 27 | // versionCmd represents the version command 28 | var versionCmd = &cobra.Command{ 29 | Use: "version", 30 | Short: "Print the current version, then exit.", 31 | Run: func(cmd *cobra.Command, args []string) { 32 | fmt.Println(version) 33 | os.Exit(0) 34 | }, 35 | } 36 | 37 | func init() { 38 | rootCmd.AddCommand(versionCmd) 39 | } 40 | -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | router: chi 3 | outputAsLibrary: true 4 | # onlyInterfaces: true 5 | packageName: gorge 6 | sourceFolder: openapi 7 | -------------------------------------------------------------------------------- /defaults.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Set uid of process to this users uid 3 | user: "" 4 | # Set gid of process to this groups gid 5 | group: "" 6 | # The forge api version to use. Currently only v3 is supported. 7 | api-version: v3 8 | # The backend type to use. Currently only filesystem is supported. 9 | backend: filesystem 10 | # Max seconds to keep the cached responses. 11 | cache-max-age: 86400 12 | # The host to bind the webservice to. 13 | bind: 127.0.0.1 14 | # The prefixes of requests to cache responses from. Multiple entries must be separated by comma. 15 | cache-prefixes: /v3/files 16 | # Cache responses by the full request URI (incl. query fragments) instead of only the request path 17 | cache-by-full-request-uri: false 18 | # Value of the `Access-Control-Allow-Origin` header. 19 | cors: "*" 20 | # Enables the dev mode. 21 | dev: false 22 | # Drop privileges if running as root (user & group options must be set) 23 | drop-privileges: false 24 | # List of comma separated upstream forge(s) to use when local requests return 404 25 | fallback-proxy: 26 | # The prefixes of requests to send to the proxies. Multiple entries must be separated by comma. 27 | proxy-prefixes: /v3 28 | # Import proxied modules into local backend. 29 | import-proxied-releases: false 30 | # Path to local modules. 31 | modulesdir: ~/.gorge/modules 32 | # Seconds between scans of directory containing all the modules 33 | modules-scan-sec: 0 34 | # Disable cache functionality. 35 | no-cache: false 36 | # Port to bind the webservice to. 37 | port: 8080 38 | # The jwt secret used in the protected endpoint validation 39 | jwt-secret: changeme 40 | # The path to write the jwt token to 41 | jwt-token-path: ~/.gorge/token 42 | # Path to tls cert file 43 | tls-cert: "" 44 | # Path to tls key file 45 | tls-key: "" 46 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dadav/gorge 2 | 3 | go 1.23 4 | 5 | toolchain go1.23.5 6 | 7 | require ( 8 | github.com/a-h/templ v0.3.833 9 | github.com/dadav/stampede v0.0.0-20241228173147-dd16def44490 10 | github.com/go-chi/chi/v5 v5.2.1 11 | github.com/go-chi/cors v1.2.1 12 | github.com/go-chi/jwtauth/v5 v5.3.2 13 | github.com/hashicorp/go-version v1.7.0 14 | github.com/mitchellh/go-homedir v1.1.0 15 | github.com/spf13/cobra v1.9.1 16 | github.com/spf13/pflag v1.0.6 17 | github.com/spf13/viper v1.19.0 18 | go.uber.org/zap v1.27.0 19 | golang.org/x/sync v0.10.0 20 | ) 21 | 22 | require ( 23 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 24 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect 25 | github.com/fsnotify/fsnotify v1.7.0 // indirect 26 | github.com/goccy/go-json v0.10.3 // indirect 27 | github.com/goware/singleflight v0.2.0 // indirect 28 | github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect 29 | github.com/hashicorp/hcl v1.0.0 // indirect 30 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 31 | github.com/lestrrat-go/blackmagic v1.0.2 // indirect 32 | github.com/lestrrat-go/httpcc v1.0.1 // indirect 33 | github.com/lestrrat-go/httprc v1.0.6 // indirect 34 | github.com/lestrrat-go/iter v1.0.2 // indirect 35 | github.com/lestrrat-go/jwx/v2 v2.1.3 // indirect 36 | github.com/lestrrat-go/option v1.0.1 // indirect 37 | github.com/magiconair/properties v1.8.7 // indirect 38 | github.com/mitchellh/mapstructure v1.5.0 // indirect 39 | github.com/pelletier/go-toml/v2 v2.2.2 // indirect 40 | github.com/sagikazarmark/locafero v0.6.0 // indirect 41 | github.com/sagikazarmark/slog-shim v0.1.0 // indirect 42 | github.com/segmentio/asm v1.2.0 // indirect 43 | github.com/sourcegraph/conc v0.3.0 // indirect 44 | github.com/spf13/afero v1.11.0 // indirect 45 | github.com/spf13/cast v1.7.0 // indirect 46 | github.com/stretchr/testify v1.10.0 // indirect 47 | github.com/subosito/gotenv v1.6.0 // indirect 48 | go.uber.org/multierr v1.11.0 // indirect 49 | golang.org/x/crypto v0.31.0 // indirect 50 | golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect 51 | golang.org/x/sys v0.28.0 // indirect 52 | golang.org/x/text v0.21.0 // indirect 53 | gopkg.in/ini.v1 v1.67.0 // indirect 54 | gopkg.in/yaml.v3 v3.0.1 // indirect 55 | ) 56 | -------------------------------------------------------------------------------- /gorge.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Gorge is a puppet forge server written in Go 3 | 4 | [Service] 5 | Type=simple 6 | ExecStart=/usr/bin/gorge --config /etc/gorge.yaml serve 7 | Restart=on-failure 8 | NoNewPrivileges=yes 9 | PrivateTmp=yes 10 | DevicePolicy=closed 11 | ProtectControlGroups=yes 12 | ProtectKernelModules=yes 13 | ProtectKernelTunables=yes 14 | RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK 15 | RestrictNamespaces=yes 16 | RestrictRealtime=yes 17 | RestrictSUIDSGID=yes 18 | MemoryDenyWriteExecute=yes 19 | LockPersonality=yes 20 | ProtectClock=yes 21 | ProtectHostname=yes 22 | PrivateUsers=yes 23 | 24 | [Install] 25 | WantedBy=multi-user.target 26 | -------------------------------------------------------------------------------- /helm/README.md: -------------------------------------------------------------------------------- 1 | # ⚡ Helm 2 | 3 | This directory contains the gorge helm chart. 4 | 5 | You can use this to easily install gorge in kubernetes. 6 | -------------------------------------------------------------------------------- /helm/gorge/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/gorge/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/dadav/helm-schema 4 | rev: 0.11.4 5 | hooks: 6 | - id: helm-schema 7 | # for all available options: helm-schema -h 8 | args: 9 | # directory to search recursively within for charts 10 | - --chart-search-root=. 11 | 12 | # don't analyze dependencies 13 | - --no-dependencies 14 | 15 | # add references to values file if not exist 16 | - --add-schema-reference 17 | 18 | # list of fields to skip from being created by default 19 | # e.g. generate a relatively permissive schema 20 | # - "--skip-auto-generation=required,additionalProperties" 21 | -------------------------------------------------------------------------------- /helm/gorge/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: gorge 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: 0.4.2-alpha 25 | -------------------------------------------------------------------------------- /helm/gorge/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: gorge 6 | spec: 7 | replicas: {{ .Values.replicaCount }} 8 | selector: 9 | matchLabels: 10 | app: gorge 11 | template: 12 | metadata: 13 | {{- with .Values.podAnnotations }} 14 | annotations: 15 | {{- toYaml . | nindent 8 }} 16 | {{- end }} 17 | labels: 18 | app: gorge 19 | spec: 20 | {{- with .Values.imagePullSecrets }} 21 | imagePullSecrets: 22 | {{- toYaml . | nindent 8 }} 23 | {{- end }} 24 | serviceAccountName: {{ .Values.serviceAccount.name }} 25 | containers: 26 | - name: {{ .Chart.Name }} 27 | securityContext: 28 | {{- toYaml .Values.securityContext | nindent 12 }} 29 | image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 30 | imagePullPolicy: {{ .Values.image.pullPolicy }} 31 | args: 32 | - serve 33 | - --modulesdir=/modules 34 | - --bind=0.0.0.0 35 | - --port=8080 36 | - --fallback-proxy=https://forge.puppetlabs.com 37 | - --import-proxied-releases 38 | - --modules-scan-sec=2 39 | ports: 40 | - name: http 41 | containerPort: 8080 42 | protocol: TCP 43 | livenessProbe: 44 | httpGet: 45 | path: /livez 46 | port: http 47 | readinessProbe: 48 | httpGet: 49 | path: /readyz 50 | port: http 51 | resources: 52 | {{- toYaml .Values.resources | nindent 12 }} 53 | volumeMounts: 54 | - mountPath: /modules 55 | name: modules 56 | volumes: 57 | - name: modules 58 | {{- if .Values.persistence.enabled }} 59 | persistentVolumeClaim: 60 | claimName: gorge 61 | {{- else }} 62 | emptyDir: {} 63 | {{- end }} 64 | {{- with .Values.nodeSelector }} 65 | nodeSelector: 66 | {{- toYaml . | nindent 8 }} 67 | {{- end }} 68 | {{- with .Values.affinity }} 69 | affinity: 70 | {{- toYaml . | nindent 8 }} 71 | {{- end }} 72 | {{- with .Values.tolerations }} 73 | tolerations: 74 | {{- toYaml . | nindent 8 }} 75 | {{- end }} 76 | -------------------------------------------------------------------------------- /helm/gorge/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if (and (.Values.ingress.enabled) (not .Values.openshift)) }} 2 | --- 3 | apiVersion: networking.k8s.io/v1 4 | kind: Ingress 5 | metadata: 6 | name: gorge 7 | {{- with .Values.ingress.annotations }} 8 | annotations: 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | {{- with .Values.ingress.className }} 13 | ingressClassName: {{ . }} 14 | {{- end }} 15 | rules: 16 | - host: {{ .Values.ingress.host }} 17 | http: 18 | paths: 19 | - pathType: Prefix 20 | path: "/" 21 | backend: 22 | service: 23 | name: gorge 24 | port: 25 | name: http 26 | {{- end }} 27 | -------------------------------------------------------------------------------- /helm/gorge/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.persistence.enabled }} 2 | --- 3 | apiVersion: v1 4 | kind: PersistentVolumeClaim 5 | metadata: 6 | name: gorge 7 | spec: 8 | {{- with .Values.persistence.storageClass }} 9 | storageClassName: {{ . }} 10 | {{- end }} 11 | accessModes: 12 | - ReadWriteOnce 13 | resources: 14 | requests: 15 | storage: {{ .Values.persistence.size }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /helm/gorge/templates/route.yaml: -------------------------------------------------------------------------------- 1 | {{- if (and (.Values.ingress.enabled) (.Values.openshift)) }} 2 | --- 3 | apiVersion: route.openshift.io/v1 4 | kind: Route 5 | metadata: 6 | name: gorge 7 | {{- with .Values.ingress.annotations }} 8 | annotations: 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | spec: 12 | host: {{ .Values.ingress.host }} 13 | port: 14 | targetPort: http 15 | to: 16 | kind: Service 17 | name: gorge 18 | {{- end }} 19 | -------------------------------------------------------------------------------- /helm/gorge/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: gorge 5 | spec: 6 | type: ClusterIP 7 | ports: 8 | - port: 8080 9 | targetPort: http 10 | protocol: TCP 11 | name: http 12 | selector: 13 | app: gorge 14 | -------------------------------------------------------------------------------- /helm/gorge/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ .Values.serviceAccount.name }} 6 | {{- with .Values.serviceAccount.annotations }} 7 | annotations: 8 | {{- toYaml . | nindent 4 }} 9 | {{- end }} 10 | automountServiceAccountToken: {{ .Values.serviceAccount.automount }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /helm/gorge/values.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=values.schema.json 2 | --- 3 | # @schema 4 | # type: "integer" 5 | # @schema 6 | # -- Number of pods 7 | replicaCount: 1 8 | 9 | # @schema 10 | # type: "boolean" 11 | # @schema 12 | # -- Enables openshift mode (routes) 13 | openshift: false 14 | 15 | # -- Configure persistency 16 | persistence: 17 | # -- Toggle persistency on / off 18 | enabled: true 19 | # -- The storageClass to use in the pvc 20 | storageClass: "" 21 | # -- The size to request in the pvc 22 | size: 1Gi 23 | 24 | # -- Image related options 25 | image: 26 | # @schema 27 | # type: string 28 | # @schema 29 | # -- Registry to use. 30 | registry: ghcr.io 31 | # @schema 32 | # type: string 33 | # required: true 34 | # @schema 35 | # -- Repo to use. 36 | repository: dadav/gorge 37 | # @schema 38 | # type: string 39 | # @schema 40 | # -- Sets the pull policy. 41 | pullPolicy: IfNotPresent 42 | # @schema 43 | # type: string 44 | # @schema 45 | # -- Image tag to use. 46 | tag: latest@sha256:94513919cc2ba1995635402e238b856baf3cc38663737eaec8fa2708e447136f 47 | 48 | # @schema 49 | # type: array 50 | # items: 51 | # type: object 52 | # properties: 53 | # url: 54 | # type: string 55 | # required: true 56 | # username: 57 | # type: string 58 | # required: true 59 | # password: 60 | # type: string 61 | # required: true 62 | # @schema 63 | # -- Optional pullsecrets required to get the gorge image. 64 | imagePullSecrets: [] 65 | 66 | # -- ServiceAccount related options 67 | serviceAccount: 68 | # -- Specifies whether a service account should be created 69 | create: true 70 | # -- Automatically mount a ServiceAccount's API credentials? 71 | automount: true 72 | # -- Annotations to add to the service account 73 | annotations: {} 74 | # -- The name of the service account to use. 75 | name: "gorge" 76 | 77 | # -- Annotations used in the pods 78 | podAnnotations: {} 79 | 80 | # -- Container securityContexts 81 | securityContext: {} 82 | # capabilities: 83 | # drop: 84 | # - ALL 85 | # readOnlyRootFilesystem: true 86 | # runAsNonRoot: true 87 | # runAsUser: 1000 88 | 89 | # -- Ingress / Route related options 90 | ingress: 91 | # -- On/Off toggle 92 | enabled: false 93 | # -- Ingress className, will be ignored if openshift=true 94 | className: "" 95 | # -- Ingress/route annotations 96 | annotations: {} 97 | # -- Hostname 98 | host: foo.example.com 99 | 100 | 101 | resources: 102 | requests: 103 | # @schema 104 | # oneOf: 105 | # - type: "integer" 106 | # - type: "string" 107 | # pattern: ^\d+m$ 108 | # @schema 109 | # -- Minimum required cpu 110 | cpu: 100m 111 | # @schema 112 | # type: "string" 113 | # pattern: ^\d+[MTPG]i$ 114 | # @schema 115 | # -- Minimum required memory 116 | memory: 128Mi 117 | limits: 118 | # @schema 119 | # oneOf: 120 | # - type: "integer" 121 | # - type: "string" 122 | # pattern: ^\d+m$ 123 | # - type: "null" 124 | # @schema 125 | # -- Maximum cpu 126 | cpu: 1 127 | # @schema 128 | # type: "string" 129 | # pattern: ^\d+[MTPG]i$ 130 | # @schema 131 | # -- Maximum memory 132 | memory: 128Mi 133 | 134 | # -- Select deployment nodes 135 | nodeSelector: {} 136 | 137 | # -- Add tolerations for nodes 138 | tolerations: [] 139 | 140 | # -- Configure node affinity 141 | affinity: {} 142 | -------------------------------------------------------------------------------- /internal/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | var ( 4 | User string 5 | Group string 6 | ApiVersion string 7 | Port int 8 | Bind string 9 | Dev bool 10 | DropPrivileges bool 11 | UI bool 12 | ModulesDir string 13 | ModulesScanSec int 14 | Backend string 15 | CORSOrigins string 16 | FallbackProxyUrl string 17 | NoCache bool 18 | CachePrefixes string 19 | ProxyPrefixes string 20 | CacheByFullRequestURI bool 21 | CacheMaxAge int64 22 | ImportProxiedReleases bool 23 | JwtSecret string 24 | TlsCertPath string 25 | TlsKeyPath string 26 | JwtTokenPath string 27 | ) 28 | -------------------------------------------------------------------------------- /internal/log/zap.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "go.uber.org/zap" 5 | "go.uber.org/zap/zapcore" 6 | ) 7 | 8 | var Log *zap.SugaredLogger 9 | 10 | func Setup(dev bool) { 11 | var logger *zap.Logger 12 | if dev { 13 | config := zap.NewDevelopmentConfig() 14 | config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder 15 | logger, _ = config.Build() 16 | } else { 17 | logger, _ = zap.NewProduction() 18 | } 19 | defer logger.Sync() 20 | Log = logger.Sugar() 21 | } 22 | -------------------------------------------------------------------------------- /internal/middleware/auth.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chi/jwtauth/v5" 7 | ) 8 | 9 | func AuthMiddleware(tokenAuth *jwtauth.JWTAuth, isProtected func(*http.Request) bool) func(next http.Handler) http.Handler { 10 | return func(next http.Handler) http.Handler { 11 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 12 | if isProtected(r) { 13 | jwtauth.Verifier(tokenAuth)(jwtauth.Authenticator(tokenAuth)(next)).ServeHTTP(w, r) 14 | return 15 | } 16 | next.ServeHTTP(w, r) 17 | }) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /internal/middleware/proxy.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "bytes" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | 9 | "github.com/dadav/gorge/internal/log" 10 | ) 11 | 12 | // capturedResponseWriter is a custom response writer that captures the response status 13 | type capturedResponseWriter struct { 14 | http.ResponseWriter 15 | body *bytes.Buffer 16 | status int 17 | } 18 | 19 | func NewCapturedResponseWriter(w http.ResponseWriter) *capturedResponseWriter { 20 | return &capturedResponseWriter{ 21 | ResponseWriter: w, 22 | body: new(bytes.Buffer), 23 | } 24 | } 25 | 26 | func (w *capturedResponseWriter) WriteHeader(code int) { 27 | w.status = code 28 | } 29 | 30 | func (w *capturedResponseWriter) Write(body []byte) (int, error) { 31 | return w.body.Write(body) 32 | } 33 | 34 | func (w *capturedResponseWriter) sendCapturedResponse() { 35 | w.ResponseWriter.WriteHeader(w.status) 36 | w.ResponseWriter.Write(w.body.Bytes()) 37 | } 38 | 39 | func NewSingleHostReverseProxy(target *url.URL) *httputil.ReverseProxy { 40 | return &httputil.ReverseProxy{ 41 | Director: func(req *http.Request) { 42 | req.URL.Scheme = target.Scheme 43 | req.URL.Host = target.Host 44 | req.Host = target.Host 45 | }, 46 | } 47 | } 48 | 49 | func ProxyFallback(upstreamHost string, forwardToProxy func(*http.Request, int) bool, proxiedResponseCb func(*http.Response)) func(next http.Handler) http.Handler { 50 | return func(next http.Handler) http.Handler { 51 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 52 | // Store original headers before any modifications 53 | originalHeaders := make(http.Header) 54 | for k, v := range w.Header() { 55 | originalHeaders[k] = v 56 | } 57 | 58 | capturedResponseWriter := NewCapturedResponseWriter(w) 59 | next.ServeHTTP(capturedResponseWriter, r) 60 | 61 | if forwardToProxy(r, capturedResponseWriter.status) { 62 | log.Log.Infof("Forwarding request to %s\n", upstreamHost) 63 | u, err := url.Parse(upstreamHost) 64 | if err != nil { 65 | log.Log.Error(err) 66 | // Restore original headers before sending captured response 67 | for k, v := range originalHeaders { 68 | w.Header()[k] = v 69 | } 70 | capturedResponseWriter.sendCapturedResponse() 71 | return 72 | } 73 | 74 | for k := range w.Header() { 75 | w.Header().Del(k) 76 | } 77 | 78 | proxy := NewSingleHostReverseProxy(u) 79 | 80 | proxy.ModifyResponse = func(r *http.Response) error { 81 | proxiedResponseCb(r) 82 | return nil 83 | } 84 | 85 | // if some error occurs, return the original content 86 | proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { 87 | log.Log.Error(err) 88 | // Restore original headers before sending captured response 89 | for k, v := range originalHeaders { 90 | w.Header()[k] = v 91 | } 92 | capturedResponseWriter.sendCapturedResponse() 93 | } 94 | 95 | stats := r.Context().Value("stats").(*Statistics) 96 | stats.Mutex.Lock() 97 | stats.ProxiedConnections++ 98 | stats.ProxiedConnectionsPerEndpoint[r.URL.Path]++ 99 | stats.Mutex.Unlock() 100 | 101 | proxy.ServeHTTP(w, r) 102 | return 103 | } 104 | 105 | // If the response status is not 404, serve the original response 106 | // Restore original headers before sending captured response 107 | for k, v := range originalHeaders { 108 | w.Header()[k] = v 109 | } 110 | capturedResponseWriter.sendCapturedResponse() 111 | }) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /internal/middleware/response_wrapper.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import "net/http" 4 | 5 | type ResponseWrapper struct { 6 | http.ResponseWriter 7 | written bool 8 | } 9 | 10 | func NewResponseWrapper(w http.ResponseWriter) *ResponseWrapper { 11 | return &ResponseWrapper{ResponseWriter: w} 12 | } 13 | 14 | func (w *ResponseWrapper) Write(b []byte) (int, error) { 15 | w.written = true 16 | return w.ResponseWriter.Write(b) 17 | } 18 | 19 | func (w *ResponseWrapper) WriteHeader(statusCode int) { 20 | w.written = true 21 | w.ResponseWriter.WriteHeader(statusCode) 22 | } 23 | 24 | func (w *ResponseWrapper) WasWritten() bool { 25 | return w.written 26 | } 27 | -------------------------------------------------------------------------------- /internal/middleware/stats.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "net/http" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type Statistics struct { 10 | ActiveConnections int 11 | TotalConnections int 12 | TotalResponseTime time.Duration 13 | TotalCacheHits int 14 | TotalCacheMisses int 15 | ConnectionsPerEndpoint map[string]int 16 | ResponseTimePerEndpoint map[string]time.Duration 17 | CacheHitsPerEndpoint map[string]int 18 | CacheMissesPerEndpoint map[string]int 19 | Mutex sync.Mutex 20 | ProxiedConnections int 21 | ProxiedConnectionsPerEndpoint map[string]int 22 | } 23 | 24 | func NewStatistics() *Statistics { 25 | return &Statistics{ 26 | ActiveConnections: 0, 27 | TotalConnections: 0, 28 | TotalResponseTime: 0, 29 | TotalCacheHits: 0, 30 | TotalCacheMisses: 0, 31 | ConnectionsPerEndpoint: make(map[string]int), 32 | CacheHitsPerEndpoint: make(map[string]int), 33 | CacheMissesPerEndpoint: make(map[string]int), 34 | ResponseTimePerEndpoint: make(map[string]time.Duration), 35 | ProxiedConnections: 0, 36 | ProxiedConnectionsPerEndpoint: make(map[string]int), 37 | } 38 | } 39 | 40 | func StatisticsMiddleware(stats *Statistics) func(next http.Handler) http.Handler { 41 | return func(next http.Handler) http.Handler { 42 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 43 | start := time.Now() 44 | stats.Mutex.Lock() 45 | stats.ActiveConnections++ 46 | stats.TotalConnections++ 47 | stats.ConnectionsPerEndpoint[r.URL.Path]++ 48 | 49 | stats.Mutex.Unlock() 50 | 51 | defer func() { 52 | duration := time.Since(start) 53 | stats.Mutex.Lock() 54 | stats.ActiveConnections-- 55 | stats.TotalResponseTime += duration 56 | stats.ResponseTimePerEndpoint[r.URL.Path] += duration 57 | stats.Mutex.Unlock() 58 | }() 59 | 60 | next.ServeHTTP(w, r) 61 | }) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /internal/middleware/useragent.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | type UserAgentNotSetResponse struct { 9 | Message string `json:"message,omitempty"` 10 | Errors []string `json:"errors,omitempty"` 11 | } 12 | 13 | func RequireUserAgent(next http.Handler) http.Handler { 14 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 | userAgent := r.Header.Get("User-Agent") 16 | if userAgent == "" { 17 | errorResponse := UserAgentNotSetResponse{ 18 | Message: "User-Agent header is missing", 19 | Errors: []string{"User-Agent must have some value"}, 20 | } 21 | jsonError, err := json.Marshal(errorResponse) 22 | if err != nil { 23 | http.Error(w, "Internal Server Error", http.StatusInternalServerError) 24 | return 25 | } 26 | w.Header().Set("Content-Type", "application/json") 27 | w.WriteHeader(http.StatusBadRequest) 28 | w.Write(jsonError) 29 | return 30 | } 31 | next.ServeHTTP(w, r) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /internal/model/module_metadata.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type SupportedOS struct { 4 | Name string `json:"operatingsystem"` 5 | Releases []string `json:"operatingsystemrelease,omitempty"` 6 | } 7 | 8 | type ModuleDependency struct { 9 | Name string `json:"name"` 10 | VersionRequirement string `json:"version_requirement,omitempty"` 11 | } 12 | 13 | type ModuleRequirement ModuleDependency 14 | 15 | type ReleaseMetadata struct { 16 | Name string `json:"name"` 17 | Version string `json:"version"` 18 | Author string `json:"author"` 19 | License string `json:"license"` 20 | Summary string `json:"summary"` 21 | Source string `json:"source"` 22 | Dependencies []ModuleDependency `json:"dependencies"` 23 | Requirements []ModuleRequirement `json:"requirements,omitempty"` 24 | ProjectUrl string `json:"project_url,omitempty"` 25 | IssuesUrl string `json:"issues_url,omitempty"` 26 | OperatingsystemSupport []SupportedOS `json:"operatingsystem_support,omitempty"` 27 | Tags []string `json:"tags,omitempty"` 28 | } 29 | -------------------------------------------------------------------------------- /internal/utils/privileges.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | // +build !windows 3 | 4 | package utils 5 | 6 | import ( 7 | "errors" 8 | "os" 9 | "os/user" 10 | "strconv" 11 | "syscall" 12 | ) 13 | 14 | func IsRoot() bool { 15 | return os.Geteuid() == 0 16 | } 17 | 18 | func DropPrivileges(newUid, newGid string) error { 19 | if newUid == "" { 20 | return errors.New("user option is empty, cant drop privileges") 21 | } 22 | 23 | if newGid == "" { 24 | return errors.New("group option is unset, cant drop privileges") 25 | } 26 | 27 | gid, err := strconv.Atoi(newGid) 28 | if err != nil { 29 | g, err := user.LookupGroup(newGid) 30 | if err != nil { 31 | return err 32 | } 33 | gid, err = strconv.Atoi(g.Gid) 34 | if err != nil { 35 | return err 36 | } 37 | } 38 | 39 | if err = syscall.Setgid(gid); err != nil { 40 | return err 41 | } 42 | 43 | uid, err := strconv.Atoi(newUid) 44 | if err != nil { 45 | u, err := user.Lookup(newUid) 46 | if err != nil { 47 | return err 48 | } 49 | uid, err = strconv.Atoi(u.Uid) 50 | if err != nil { 51 | return err 52 | } 53 | } 54 | if err = syscall.Setuid(uid); err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | } 60 | -------------------------------------------------------------------------------- /internal/utils/privileges_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package utils 5 | 6 | import ( 7 | "errors" 8 | ) 9 | 10 | func IsRoot() bool { 11 | return false 12 | } 13 | 14 | func DropPrivileges(newUid, newGid string) error { 15 | return errors.New("cant drop privileges in windows") 16 | } 17 | -------------------------------------------------------------------------------- /internal/utils/tilde.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os/user" 5 | "strings" 6 | ) 7 | 8 | // ExpandTilde replaces ~ with the homedir of the current user 9 | func ExpandTilde(path string) (string, error) { 10 | u, err := user.Current() 11 | if err != nil { 12 | return "", err 13 | } 14 | return strings.Replace(path, "~", u.HomeDir, 1), nil 15 | } 16 | -------------------------------------------------------------------------------- /internal/v3/api/search_filter.go: -------------------------------------------------------------------------------- 1 | package v3 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net/http" 7 | 8 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 9 | ) 10 | 11 | type SearchFilterOperationsApi struct { 12 | gen.SearchFilterOperationsAPIServicer 13 | } 14 | 15 | func NewSearchFilterOperationsApi() *SearchFilterOperationsApi { 16 | return &SearchFilterOperationsApi{} 17 | } 18 | 19 | // AddSearchFilter - Create search filter 20 | func (s *SearchFilterOperationsApi) AddSearchFilter(ctx context.Context, searchFilterSlug string, withHtml bool, includeFields []string, excludeFields []string, ifModifiedSince string) (gen.ImplResponse, error) { 21 | // TODO - update AddSearchFilter with the required logic for this service method. 22 | // Add api_search_filter_operations_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. 23 | 24 | // TODO: Uncomment the next line to return response Response(200, SearchFilter{}) or use other options such as http.Ok ... 25 | // return Response(200, SearchFilter{}), nil 26 | 27 | // TODO: Uncomment the next line to return response Response(304, {}) or use other options such as http.Ok ... 28 | // return Response(304, nil),nil 29 | 30 | // TODO: Uncomment the next line to return response Response(400, GetFile400Response{}) or use other options such as http.Ok ... 31 | // return Response(400, GetFile400Response{}), nil 32 | 33 | // TODO: Uncomment the next line to return response Response(404, GetFile404Response{}) or use other options such as http.Ok ... 34 | // return Response(404, GetFile404Response{}), nil 35 | 36 | // TODO: Uncomment the next line to return response Response(409, AddSearchFilter409Response{}) or use other options such as http.Ok ... 37 | // return Response(409, AddSearchFilter409Response{}), nil 38 | 39 | return gen.Response(http.StatusNotImplemented, nil), errors.New("AddSearchFilter method not implemented") 40 | } 41 | 42 | // DeleteUserSearchFilter - Delete search filter by ID 43 | func (s *SearchFilterOperationsApi) DeleteUserSearchFilter(ctx context.Context, id int32) (gen.ImplResponse, error) { 44 | // TODO - update DeleteUserSearchFilter with the required logic for this service method. 45 | // Add api_search_filter_operations_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. 46 | 47 | // TODO: Uncomment the next line to return response Response(204, {}) or use other options such as http.Ok ... 48 | // return Response(204, nil),nil 49 | 50 | // TODO: Uncomment the next line to return response Response(403, DeleteUserSearchFilter403Response{}) or use other options such as http.Ok ... 51 | // return Response(403, DeleteUserSearchFilter403Response{}), nil 52 | 53 | // TODO: Uncomment the next line to return response Response(404, GetFile404Response{}) or use other options such as http.Ok ... 54 | // return Response(404, GetFile404Response{}), nil 55 | 56 | return gen.Response(http.StatusNotImplemented, nil), errors.New("DeleteUserSearchFilter method not implemented") 57 | } 58 | 59 | // GetUserSearchFilters - Get user's search filters 60 | func (s *SearchFilterOperationsApi) GetUserSearchFilters(ctx context.Context) (gen.ImplResponse, error) { 61 | // TODO - update GetUserSearchFilters with the required logic for this service method. 62 | // Add api_search_filter_operations_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. 63 | 64 | // TODO: Uncomment the next line to return response Response(200, SearchFilterResponse{}) or use other options such as http.Ok ... 65 | // return Response(200, SearchFilterResponse{}), nil 66 | 67 | // TODO: Uncomment the next line to return response Response(400, GetFile400Response{}) or use other options such as http.Ok ... 68 | // return Response(400, GetFile400Response{}), nil 69 | 70 | // TODO: Uncomment the next line to return response Response(401, GetUserSearchFilters401Response{}) or use other options such as http.Ok ... 71 | // return Response(401, GetUserSearchFilters401Response{}), nil 72 | 73 | // TODO: Uncomment the next line to return response Response(404, GetFile404Response{}) or use other options such as http.Ok ... 74 | // return Response(404, GetFile404Response{}), nil 75 | 76 | return gen.Response(http.StatusNotImplemented, nil), errors.New("GetUserSearchFilters method not implemented") 77 | } 78 | -------------------------------------------------------------------------------- /internal/v3/api/user.go: -------------------------------------------------------------------------------- 1 | package v3 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "net/http" 7 | 8 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 9 | ) 10 | 11 | type UserOperationsApi struct { 12 | gen.UserOperationsAPIServicer 13 | } 14 | 15 | func NewUserOperationsApi() *UserOperationsApi { 16 | return &UserOperationsApi{} 17 | } 18 | 19 | // GetUser - Fetch user 20 | func (s *UserOperationsApi) GetUser(ctx context.Context, userSlug string, withHtml bool, includeFields []string, excludeFields []string, ifModifiedSince string) (gen.ImplResponse, error) { 21 | // TODO - update GetUser with the required logic for this service method. 22 | // Add api_user_operations_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. 23 | 24 | // TODO: Uncomment the next line to return response Response(200, User{}) or use other options such as http.Ok ... 25 | // return gen.Response(200, User{}), nil 26 | 27 | // TODO: Uncomment the next line to return response Response(304, {}) or use other options such as http.Ok ... 28 | // return gen.Response(304, nil),nil 29 | 30 | // TODO: Uncomment the next line to return response Response(400, GetFile400Response{}) or use other options such as http.Ok ... 31 | // return gen.Response(400, GetFile400Response{}), nil 32 | 33 | // TODO: Uncomment the next line to return response Response(404, GetFile404Response{}) or use other options such as http.Ok ... 34 | // return gen.Response(404, GetFile404Response{}), nil 35 | 36 | return gen.Response(http.StatusNotImplemented, nil), errors.New("GetUser method not implemented") 37 | } 38 | 39 | // GetUsers - List users 40 | func (s *UserOperationsApi) GetUsers(ctx context.Context, limit int32, offset int32, sortBy string, withHtml bool, includeFields []string, excludeFields []string, ifModifiedSince string) (gen.ImplResponse, error) { 41 | // TODO - update GetUsers with the required logic for this service method. 42 | // Add api_user_operations_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. 43 | 44 | // TODO: Uncomment the next line to return response Response(200, GetUsers200Response{}) or use other options such as http.Ok ... 45 | // return gen.Response(200, GetUsers200Response{}), nil 46 | 47 | // TODO: Uncomment the next line to return response Response(304, {}) or use other options such as http.Ok ... 48 | // return gen.Response(304, nil),nil 49 | 50 | return gen.Response(http.StatusNotImplemented, nil), errors.New("GetUsers method not implemented") 51 | } 52 | -------------------------------------------------------------------------------- /internal/v3/backend/config.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | var ConfiguredBackend Backend 4 | -------------------------------------------------------------------------------- /internal/v3/backend/interface.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 4 | 5 | type Backend interface { 6 | // LoadModules loads modules into memory 7 | LoadModules() error 8 | 9 | // GetAllModules returns a list of all modules 10 | GetAllModules() ([]*gen.Module, error) 11 | 12 | // GetModuleBySlug contains a map to modules 13 | GetModuleBySlug(slug string) (*gen.Module, error) 14 | 15 | // GetAllReleases returns a list of all releases 16 | GetAllReleases() ([]*gen.Release, error) 17 | 18 | // GetReleaseBySlug returns a release by slug 19 | GetReleaseBySlug(slug string) (*gen.Release, error) 20 | 21 | // AddRelease adds a new release 22 | AddRelease(data []byte) (*gen.Release, error) 23 | 24 | // DeleteModuleBySlug deletes a module 25 | DeleteModuleBySlug(slug string) error 26 | 27 | // DeleteReleaseBySlug deletes a release by slug 28 | DeleteReleaseBySlug(slug string) error 29 | 30 | // UpdateModule updates a module 31 | UpdateModule(module *gen.Module) error 32 | } 33 | -------------------------------------------------------------------------------- /internal/v3/ui/assets.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "embed" 5 | "net/http" 6 | ) 7 | 8 | //go:embed all:assets 9 | var assets embed.FS 10 | 11 | func HandleAssets() http.Handler { 12 | return http.FileServer(http.FS(assets)) 13 | } 14 | -------------------------------------------------------------------------------- /internal/v3/ui/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadav/gorge/7e641fa55feceeaef9a63edd94d0bf49f4b2af05/internal/v3/ui/assets/favicon.ico -------------------------------------------------------------------------------- /internal/v3/ui/assets/js/table-sort.js: -------------------------------------------------------------------------------- 1 | function sortTable(tableId, columnIndex) { 2 | var table = document.getElementById(tableId); 3 | var switching = true; 4 | var dir = "asc"; 5 | var switchcount = 0; 6 | 7 | while (switching) { 8 | switching = false; 9 | var rows = table.rows; 10 | 11 | for (var i = 1; i < (rows.length - 1); i++) { 12 | var shouldSwitch = false; 13 | var x = rows[i].getElementsByTagName("TD")[columnIndex]; 14 | var y = rows[i + 1].getElementsByTagName("TD")[columnIndex]; 15 | 16 | var xContent = x.innerHTML.toLowerCase(); 17 | var yContent = y.innerHTML.toLowerCase(); 18 | 19 | // Try to convert to numbers if the content looks numeric 20 | if (xContent.match(/^[\d./]+$/) && yContent.match(/^[\d./]+$/)) { 21 | xContent = parseFloat(xContent.replace(/[^\d.-]/g, '')) || xContent; 22 | yContent = parseFloat(yContent.replace(/[^\d.-]/g, '')) || yContent; 23 | } 24 | 25 | if (dir === "asc") { 26 | if (xContent > yContent) { 27 | shouldSwitch = true; 28 | break; 29 | } 30 | } else if (dir === "desc") { 31 | if (xContent < yContent) { 32 | shouldSwitch = true; 33 | break; 34 | } 35 | } 36 | } 37 | 38 | if (shouldSwitch) { 39 | rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); 40 | switching = true; 41 | switchcount++; 42 | } else { 43 | if (switchcount === 0 && dir === "asc") { 44 | dir = "desc"; 45 | switching = true; 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /internal/v3/ui/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadav/gorge/7e641fa55feceeaef9a63edd94d0bf49f4b2af05/internal/v3/ui/assets/logo.png -------------------------------------------------------------------------------- /internal/v3/ui/assets/style.css: -------------------------------------------------------------------------------- 1 | .search { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | flex-direction: column; 6 | } 7 | 8 | #query { 9 | max-width: 50%; 10 | } 11 | 12 | th[onclick] { 13 | cursor: pointer; 14 | } 15 | 16 | /* https://codepen.io/irunatbullets/pen/MWwyVOw */ 17 | .switch { 18 | display: inline-block; 19 | position: relative; 20 | transform: scale(0.7); 21 | } 22 | 23 | .switch__input { 24 | clip: rect(1px, 1px, 1px, 1px); 25 | clip-path: inset(50%); 26 | height: 1px; 27 | width: 1px; 28 | margin: -1px; 29 | overflow: hidden; 30 | padding: 0; 31 | position: absolute; 32 | } 33 | 34 | .switch__label { 35 | position: relative; 36 | display: inline-block; 37 | width: 120px; 38 | height: 60px; 39 | background-color: #2b2b2b; 40 | border: 5px solid #5b5b5b; 41 | border-radius: 9999px; 42 | cursor: pointer; 43 | transition: all 0.4s cubic-bezier(0.46, 0.03, 0.52, 0.96); 44 | } 45 | 46 | .switch__indicator { 47 | position: absolute; 48 | top: 50%; 49 | left: 50%; 50 | transform: translate(-50%, -50%) translateX(-72%); 51 | display: block; 52 | width: 40px; 53 | height: 40px; 54 | background-color: #7b7b7b; 55 | border-radius: 9999px; 56 | box-shadow: 10px 0px 0 0 rgba(0, 0, 0, 0.2) inset; 57 | } 58 | .switch__indicator::before, .switch__indicator::after { 59 | position: absolute; 60 | content: ""; 61 | display: block; 62 | background-color: #ffffff; 63 | border-radius: 9999px; 64 | } 65 | .switch__indicator::before { 66 | top: 7px; 67 | left: 7px; 68 | width: 9px; 69 | height: 9px; 70 | background-color: #ffffff; 71 | opacity: 0.6; 72 | } 73 | .switch__indicator::after { 74 | bottom: 8px; 75 | right: 6px; 76 | width: 14px; 77 | height: 14px; 78 | background-color: #ffffff; 79 | opacity: 0.8; 80 | } 81 | 82 | .switch__decoration { 83 | position: absolute; 84 | top: 65%; 85 | left: 50%; 86 | display: block; 87 | width: 5px; 88 | height: 5px; 89 | background-color: #ffffff; 90 | border-radius: 9999px; 91 | animation: twinkle 0.8s infinite -0.6s; 92 | } 93 | .switch__decoration::before, .switch__decoration::after { 94 | position: absolute; 95 | display: block; 96 | content: ""; 97 | width: 5px; 98 | height: 5px; 99 | background-color: #ffffff; 100 | border-radius: 9999px; 101 | } 102 | .switch__decoration::before { 103 | top: -20px; 104 | left: 10px; 105 | opacity: 1; 106 | animation: twinkle 0.6s infinite; 107 | } 108 | .switch__decoration::after { 109 | top: -7px; 110 | left: 30px; 111 | animation: twinkle 0.6s infinite -0.2s; 112 | } 113 | 114 | @keyframes twinkle { 115 | 50% { 116 | opacity: 0.2; 117 | } 118 | } 119 | .switch__indicator, .switch__indicator::before, .switch__indicator::after { 120 | transition: all 0.4s cubic-bezier(0.46, 0.03, 0.52, 0.96); 121 | } 122 | 123 | .switch__input:checked + .switch__label { 124 | background-color: #8fb5f5; 125 | border-color: #347cf8; 126 | } 127 | .switch__input:checked + .switch__label .switch__indicator { 128 | background-color: #ecd21f; 129 | box-shadow: none; 130 | transform: translate(-50%, -50%) translateX(72%); 131 | } 132 | .switch__input:checked + .switch__label .switch__indicator::before, .switch__input:checked + .switch__label .switch__indicator::after { 133 | display: none; 134 | } 135 | .switch__input:checked + .switch__label .switch__decoration { 136 | top: 50%; 137 | transform: translate(0%, -50%); 138 | animation: cloud 8s linear infinite; 139 | width: 20px; 140 | height: 20px; 141 | } 142 | .switch__input:checked + .switch__label .switch__decoration::before { 143 | width: 10px; 144 | height: 10px; 145 | top: auto; 146 | bottom: 0; 147 | left: -8px; 148 | animation: none; 149 | } 150 | .switch__input:checked + .switch__label .switch__decoration::after { 151 | width: 15px; 152 | height: 15px; 153 | top: auto; 154 | bottom: 0; 155 | left: 16px; 156 | animation: none; 157 | } 158 | .switch__input:checked + .switch__label .switch__decoration, .switch__input:checked + .switch__label .switch__decoration::before, .switch__input:checked + .switch__label .switch__decoration::after { 159 | border-radius: 9999px 9999px 0 0; 160 | } 161 | .switch__input:checked + .switch__label .switch__decoration::after { 162 | border-bottom-right-radius: 9999px; 163 | } 164 | 165 | @keyframes cloud { 166 | 0% { 167 | transform: translate(0%, -50%); 168 | } 169 | 50% { 170 | transform: translate(-50%, -50%); 171 | } 172 | 100% { 173 | transform: translate(0%, -50%); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /internal/v3/ui/assets/style.scss: -------------------------------------------------------------------------------- 1 | .search { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | flex-direction: column; 6 | } 7 | 8 | #query { 9 | max-width: 50%; 10 | } 11 | 12 | /* https://codepen.io/irunatbullets/pen/MWwyVOw */ 13 | .switch { 14 | display: inline-block; 15 | position: relative; 16 | transform: scale(0.7); 17 | } 18 | 19 | .switch__input { 20 | clip: rect(1px, 1px, 1px, 1px); 21 | clip-path: inset(50%); 22 | height: 1px; 23 | width: 1px; 24 | margin: -1px; 25 | overflow: hidden; 26 | padding: 0; 27 | position: absolute; 28 | } 29 | 30 | .switch__label { 31 | position: relative; 32 | display: inline-block; 33 | width: 120px; 34 | height: 60px; 35 | background-color: #2b2b2b; 36 | border: 5px solid #5b5b5b; 37 | border-radius: 9999px; 38 | cursor: pointer; 39 | transition: all 0.4s cubic-bezier(0.46, 0.03, 0.52, 0.96); 40 | } 41 | 42 | .switch__indicator { 43 | position: absolute; 44 | top: 50%; 45 | left: 50%; 46 | transform: translate(-50%, -50%) translateX(-72%); 47 | display: block; 48 | width: 40px; 49 | height: 40px; 50 | background-color: #7b7b7b; 51 | border-radius: 9999px; 52 | box-shadow: 10px 0px 0 0 rgba(#000000, 0.2) inset; 53 | 54 | &::before, 55 | &::after { 56 | position: absolute; 57 | content: ""; 58 | display: block; 59 | background-color: #ffffff; 60 | border-radius: 9999px; 61 | } 62 | 63 | &::before { 64 | top: 7px; 65 | left: 7px; 66 | width: 9px; 67 | height: 9px; 68 | background-color: #ffffff; 69 | opacity: 0.6; 70 | } 71 | 72 | &::after { 73 | bottom: 8px; 74 | right: 6px; 75 | width: 14px; 76 | height: 14px; 77 | background-color: #ffffff; 78 | opacity: 0.8; 79 | } 80 | } 81 | 82 | .switch__decoration { 83 | position: absolute; 84 | top: 65%; 85 | left: 50%; 86 | display: block; 87 | width: 5px; 88 | height: 5px; 89 | background-color: #ffffff; 90 | border-radius: 9999px; 91 | animation: twinkle 0.8s infinite -0.6s; 92 | 93 | &::before, 94 | &::after { 95 | position: absolute; 96 | display: block; 97 | content: ""; 98 | width: 5px; 99 | height: 5px; 100 | background-color: #ffffff; 101 | border-radius: 9999px; 102 | } 103 | 104 | &::before { 105 | top: -20px; 106 | left: 10px; 107 | opacity: 1; 108 | animation: twinkle 0.6s infinite; 109 | } 110 | 111 | &::after { 112 | top: -7px; 113 | left: 30px; 114 | animation: twinkle 0.6s infinite -0.2s; 115 | } 116 | } 117 | 118 | @keyframes twinkle { 119 | 50% { 120 | opacity: 0.2; 121 | } 122 | } 123 | 124 | .switch__indicator { 125 | &, 126 | &::before, 127 | &::after { 128 | transition: all 0.4s cubic-bezier(0.46, 0.03, 0.52, 0.96); 129 | } 130 | } 131 | 132 | .switch__input:checked + .switch__label { 133 | background-color: #8fb5f5; 134 | border-color: #347cf8; 135 | 136 | .switch__indicator { 137 | background-color: #ecd21f; 138 | box-shadow: none; 139 | transform: translate(-50%, -50%) translateX(72%); 140 | 141 | &::before, 142 | &::after { 143 | display: none; 144 | } 145 | } 146 | 147 | .switch__decoration { 148 | top: 50%; 149 | transform: translate(0%, -50%); 150 | animation: cloud 8s linear infinite; 151 | 152 | width: 20px; 153 | height: 20px; 154 | 155 | &::before { 156 | width: 10px; 157 | height: 10px; 158 | top: auto; 159 | bottom: 0; 160 | left: -8px; 161 | animation: none; 162 | } 163 | 164 | &::after { 165 | width: 15px; 166 | height: 15px; 167 | top: auto; 168 | bottom: 0; 169 | left: 16px; 170 | animation: none; 171 | } 172 | 173 | &, 174 | &::before, 175 | &::after { 176 | border-radius: 9999px 9999px 0 0; 177 | } 178 | 179 | &::after { 180 | border-bottom-right-radius: 9999px; 181 | } 182 | } 183 | } 184 | 185 | @keyframes cloud { 186 | 0% { 187 | transform: translate(0%, -50%); 188 | } 189 | 50% { 190 | transform: translate(-50%, -50%); 191 | } 192 | 100% { 193 | transform: translate(0%, -50%); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /internal/v3/ui/assets/theme-switcher.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Minimal theme switcher 3 | * 4 | * Pico.css - https://picocss.com 5 | * Copyright 2019-2024 - Licensed under MIT 6 | */ 7 | 8 | const themeSwitcher = { 9 | // Config 10 | _scheme: "light", 11 | rootAttribute: "data-theme", 12 | localStorageKey: "picoPreferredColorScheme", 13 | 14 | // Init 15 | init() { 16 | this.scheme = this.schemeFromLocalStorage; 17 | this.initSwitchers(); 18 | }, 19 | 20 | // Get color scheme from local storage 21 | get schemeFromLocalStorage() { 22 | return ( 23 | window.localStorage?.getItem(this.localStorageKey) ?? 24 | this.preferredColorScheme 25 | ); 26 | }, 27 | 28 | // Preferred color scheme 29 | get preferredColorScheme() { 30 | return window.matchMedia("(prefers-color-scheme: dark)").matches 31 | ? "dark" 32 | : "light"; 33 | }, 34 | 35 | // Init switchers 36 | initSwitchers() { 37 | const toggleSwitch = document.getElementById("theme-toggle"); 38 | 39 | toggleSwitch.addEventListener( 40 | "change", 41 | (e) => { 42 | // e.preventDefault(); 43 | if (e.target.checked) { 44 | this.scheme = "dark"; 45 | } else { 46 | this.scheme = "light"; 47 | } 48 | }, 49 | false, 50 | ); 51 | }, 52 | 53 | // Set scheme 54 | set scheme(scheme) { 55 | this._scheme = scheme; 56 | this.applyScheme(); 57 | this.schemeToLocalStorage(); 58 | }, 59 | 60 | // Get scheme 61 | get scheme() { 62 | return this._scheme; 63 | }, 64 | 65 | // Apply scheme 66 | applyScheme() { 67 | document 68 | .querySelector("html") 69 | ?.setAttribute(this.rootAttribute, this.scheme); 70 | }, 71 | 72 | // Store scheme to local storage 73 | schemeToLocalStorage() { 74 | window.localStorage?.setItem(this.localStorageKey, this.scheme); 75 | }, 76 | }; 77 | 78 | // Init 79 | themeSwitcher.init(); 80 | -------------------------------------------------------------------------------- /internal/v3/ui/components/author.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | "fmt" 5 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 6 | ) 7 | 8 | templ AuthorView(modules []*gen.Module) { 9 |

{ modules[0].Owner.Username }

10 |

Modules

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | for _, module := range sortModules(modules) { 20 | 21 | 24 | 27 | 28 | } 29 | 30 |
Module ↕Version ↕
22 | { module.Name } 23 | 25 | { module.CurrentRelease.Version } 26 |
31 | 32 | } 33 | -------------------------------------------------------------------------------- /internal/v3/ui/components/author_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ - DO NOT EDIT. 2 | 3 | // templ: version: v0.2.747 4 | package components 5 | 6 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 7 | 8 | import "github.com/a-h/templ" 9 | import templruntime "github.com/a-h/templ/runtime" 10 | 11 | import ( 12 | "fmt" 13 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 14 | ) 15 | 16 | func AuthorView(modules []*gen.Module) templ.Component { 17 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 18 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 19 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 20 | if !templ_7745c5c3_IsBuffer { 21 | defer func() { 22 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 23 | if templ_7745c5c3_Err == nil { 24 | templ_7745c5c3_Err = templ_7745c5c3_BufErr 25 | } 26 | }() 27 | } 28 | ctx = templ.InitializeContext(ctx) 29 | templ_7745c5c3_Var1 := templ.GetChildren(ctx) 30 | if templ_7745c5c3_Var1 == nil { 31 | templ_7745c5c3_Var1 = templ.NopComponent 32 | } 33 | ctx = templ.ClearChildren(ctx) 34 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") 35 | if templ_7745c5c3_Err != nil { 36 | return templ_7745c5c3_Err 37 | } 38 | var templ_7745c5c3_Var2 string 39 | templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(modules[0].Owner.Username) 40 | if templ_7745c5c3_Err != nil { 41 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/v3/ui/components/author.templ`, Line: 9, Col: 32} 42 | } 43 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 44 | if templ_7745c5c3_Err != nil { 45 | return templ_7745c5c3_Err 46 | } 47 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Modules

") 48 | if templ_7745c5c3_Err != nil { 49 | return templ_7745c5c3_Err 50 | } 51 | for _, module := range sortModules(modules) { 52 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 97 | if templ_7745c5c3_Err != nil { 98 | return templ_7745c5c3_Err 99 | } 100 | } 101 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Module ↕Version ↕
") 62 | if templ_7745c5c3_Err != nil { 63 | return templ_7745c5c3_Err 64 | } 65 | var templ_7745c5c3_Var4 string 66 | templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(module.Name) 67 | if templ_7745c5c3_Err != nil { 68 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/v3/ui/components/author.templ`, Line: 22, Col: 82} 69 | } 70 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) 71 | if templ_7745c5c3_Err != nil { 72 | return templ_7745c5c3_Err 73 | } 74 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 84 | if templ_7745c5c3_Err != nil { 85 | return templ_7745c5c3_Err 86 | } 87 | var templ_7745c5c3_Var6 string 88 | templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(module.CurrentRelease.Version) 89 | if templ_7745c5c3_Err != nil { 90 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/v3/ui/components/author.templ`, Line: 25, Col: 134} 91 | } 92 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) 93 | if templ_7745c5c3_Err != nil { 94 | return templ_7745c5c3_Err 95 | } 96 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") 102 | if templ_7745c5c3_Err != nil { 103 | return templ_7745c5c3_Err 104 | } 105 | return templ_7745c5c3_Err 106 | }) 107 | } 108 | -------------------------------------------------------------------------------- /internal/v3/ui/components/head.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | templ Header(title string) { 4 | 5 | 6 | 7 | 8 | { title } 9 | 10 | 11 | 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /internal/v3/ui/components/head_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ - DO NOT EDIT. 2 | 3 | // templ: version: v0.2.747 4 | package components 5 | 6 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 7 | 8 | import "github.com/a-h/templ" 9 | import templruntime "github.com/a-h/templ/runtime" 10 | 11 | func Header(title string) templ.Component { 12 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 13 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 14 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 15 | if !templ_7745c5c3_IsBuffer { 16 | defer func() { 17 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 18 | if templ_7745c5c3_Err == nil { 19 | templ_7745c5c3_Err = templ_7745c5c3_BufErr 20 | } 21 | }() 22 | } 23 | ctx = templ.InitializeContext(ctx) 24 | templ_7745c5c3_Var1 := templ.GetChildren(ctx) 25 | if templ_7745c5c3_Var1 == nil { 26 | templ_7745c5c3_Var1 = templ.NopComponent 27 | } 28 | ctx = templ.ClearChildren(ctx) 29 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 30 | if templ_7745c5c3_Err != nil { 31 | return templ_7745c5c3_Err 32 | } 33 | var templ_7745c5c3_Var2 string 34 | templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title) 35 | if templ_7745c5c3_Err != nil { 36 | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/v3/ui/components/head.templ`, Line: 8, Col: 16} 37 | } 38 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) 39 | if templ_7745c5c3_Err != nil { 40 | return templ_7745c5c3_Err 41 | } 42 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 43 | if templ_7745c5c3_Err != nil { 44 | return templ_7745c5c3_Err 45 | } 46 | return templ_7745c5c3_Err 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /internal/v3/ui/components/module.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | "fmt" 5 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 6 | ) 7 | 8 | templ ModuleView(module *gen.Module) { 9 |

{ module.Name }

10 | 11 | 12 | 13 | 16 | 19 | 20 | 21 | 24 | 27 | 28 | 29 | 32 | 41 | 42 | if len(deps(module.CurrentRelease.Metadata)) > 0 { 43 | 44 | 47 | 53 | 54 | } 55 | 56 |
14 | Name 15 | 17 | { module.Name } 18 |
22 | Author 23 | 25 | { module.Owner.Username } 26 |
30 | Versions 31 | 33 | { module.CurrentRelease.Version } (latest) 34 | for _, release := range module.Releases { 35 | if module.CurrentRelease.Version != release.Version { 36 |
37 | { release.Version } 38 | } 39 | } 40 |
45 | Dependencies 46 | 48 | for _, dep := range deps(module.CurrentRelease.Metadata) { 49 | { dep.Name } { dep.VersionRequirement } 50 |
51 | } 52 |
57 | } 58 | -------------------------------------------------------------------------------- /internal/v3/ui/components/nav.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | templ Nav(title string) { 4 | 28 | } 29 | -------------------------------------------------------------------------------- /internal/v3/ui/components/nav_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ - DO NOT EDIT. 2 | 3 | // templ: version: v0.2.747 4 | package components 5 | 6 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 7 | 8 | import "github.com/a-h/templ" 9 | import templruntime "github.com/a-h/templ/runtime" 10 | 11 | func Nav(title string) templ.Component { 12 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 13 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 14 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 15 | if !templ_7745c5c3_IsBuffer { 16 | defer func() { 17 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 18 | if templ_7745c5c3_Err == nil { 19 | templ_7745c5c3_Err = templ_7745c5c3_BufErr 20 | } 21 | }() 22 | } 23 | ctx = templ.InitializeContext(ctx) 24 | templ_7745c5c3_Var1 := templ.GetChildren(ctx) 25 | if templ_7745c5c3_Var1 == nil { 26 | templ_7745c5c3_Var1 = templ.NopComponent 27 | } 28 | ctx = templ.ClearChildren(ctx) 29 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 43 | if templ_7745c5c3_Err != nil { 44 | return templ_7745c5c3_Err 45 | } 46 | return templ_7745c5c3_Err 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /internal/v3/ui/components/page.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | templ Page(title string, content templ.Component) { 4 | 5 | 6 | @Header(title) 7 | 8 |
9 | @Nav(title) 10 |
11 |
12 | @content 13 |
14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /internal/v3/ui/components/page_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ - DO NOT EDIT. 2 | 3 | // templ: version: v0.2.747 4 | package components 5 | 6 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 7 | 8 | import "github.com/a-h/templ" 9 | import templruntime "github.com/a-h/templ/runtime" 10 | 11 | func Page(title string, content templ.Component) templ.Component { 12 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { 13 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context 14 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) 15 | if !templ_7745c5c3_IsBuffer { 16 | defer func() { 17 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) 18 | if templ_7745c5c3_Err == nil { 19 | templ_7745c5c3_Err = templ_7745c5c3_BufErr 20 | } 21 | }() 22 | } 23 | ctx = templ.InitializeContext(ctx) 24 | templ_7745c5c3_Var1 := templ.GetChildren(ctx) 25 | if templ_7745c5c3_Var1 == nil { 26 | templ_7745c5c3_Var1 = templ.NopComponent 27 | } 28 | ctx = templ.ClearChildren(ctx) 29 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") 30 | if templ_7745c5c3_Err != nil { 31 | return templ_7745c5c3_Err 32 | } 33 | templ_7745c5c3_Err = Header(title).Render(ctx, templ_7745c5c3_Buffer) 34 | if templ_7745c5c3_Err != nil { 35 | return templ_7745c5c3_Err 36 | } 37 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") 38 | if templ_7745c5c3_Err != nil { 39 | return templ_7745c5c3_Err 40 | } 41 | templ_7745c5c3_Err = Nav(title).Render(ctx, templ_7745c5c3_Buffer) 42 | if templ_7745c5c3_Err != nil { 43 | return templ_7745c5c3_Err 44 | } 45 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") 46 | if templ_7745c5c3_Err != nil { 47 | return templ_7745c5c3_Err 48 | } 49 | templ_7745c5c3_Err = content.Render(ctx, templ_7745c5c3_Buffer) 50 | if templ_7745c5c3_Err != nil { 51 | return templ_7745c5c3_Err 52 | } 53 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") 54 | if templ_7745c5c3_Err != nil { 55 | return templ_7745c5c3_Err 56 | } 57 | return templ_7745c5c3_Err 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /internal/v3/ui/components/release.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | "fmt" 5 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 6 | ) 7 | 8 | templ ReleaseView(release *gen.Release) { 9 |

{ release.Module.Name }

10 | 11 | 12 | 13 | 16 | 19 | 20 | 21 | 24 | 27 | 28 | 29 | 32 | 35 | 36 | if len(deps(release.Metadata)) > 0 { 37 | 38 | 41 | 47 | 48 | } 49 | 50 |
14 | Name 15 | 17 | { release.Module.Name } 18 |
22 | Author 23 | 25 | { release.Module.Owner.Username } 26 |
30 | Version 31 | 33 | { release.Version } (Download) 34 |
39 | Dependencies 40 | 42 | for _, dep := range deps(release.Metadata) { 43 | { dep.Name } { dep.VersionRequirement } 44 |
45 | } 46 |
51 | } 52 | -------------------------------------------------------------------------------- /internal/v3/ui/components/search.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | "fmt" 5 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 6 | ) 7 | 8 | templ SearchView(query string, modules []*gen.Module) { 9 | 45 | } 46 | 47 | templ ModuleToTableRow(module *gen.Module) { 48 | 49 | { module.Name } 50 | { module.Owner.Username } 51 | { module.CurrentRelease.Version } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /internal/v3/ui/components/statistics.templ: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | customMiddleware "github.com/dadav/gorge/internal/middleware" 5 | "strconv" 6 | "time" 7 | ) 8 | 9 | templ StatisticsView(stats *customMiddleware.Statistics) { 10 |
11 |

Statistics

12 |

ActiveConnections: { strconv.Itoa(stats.ActiveConnections) }

13 |

ProxiedConnections: { strconv.Itoa(stats.ProxiedConnections) }

14 |

TotalConnections: { strconv.Itoa(stats.TotalConnections) }

15 |

TotalResponseTime: { stats.TotalResponseTime.String() }

16 |

TotalCacheHits: { strconv.Itoa(stats.TotalCacheHits) }

17 |

TotalCacheMisses: { strconv.Itoa(stats.TotalCacheMisses) }

18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | for _, path := range getSortedKeys(stats) { 31 | 32 | 33 | 34 | 35 | 36 | 37 | if stats.CacheHitsPerEndpoint[path] > 0 || stats.CacheMissesPerEndpoint[path] > 0 { 38 | 39 | } else { 40 | 41 | } 42 | 43 | } 44 | 45 |
Path ↕Connections ↕Proxied Connections ↕Average ResponseTime ↕Total ResponseTime ↕Cache (Hits/Misses) ↕
{ path }{ strconv.Itoa(stats.ConnectionsPerEndpoint[path]) }{ strconv.Itoa(stats.ProxiedConnectionsPerEndpoint[path]) }{ (stats.ResponseTimePerEndpoint[path] / time.Duration(stats.ConnectionsPerEndpoint[path])).String() }{ stats.ResponseTimePerEndpoint[path].String() }{ strconv.Itoa(stats.CacheHitsPerEndpoint[path]) }/{ strconv.Itoa(stats.CacheMissesPerEndpoint[path]) }N/A
46 | 47 |
48 | } 49 | -------------------------------------------------------------------------------- /internal/v3/ui/components/utils.go: -------------------------------------------------------------------------------- 1 | package components 2 | 3 | import ( 4 | "encoding/json" 5 | "sort" 6 | "strings" 7 | 8 | customMiddleware "github.com/dadav/gorge/internal/middleware" 9 | model "github.com/dadav/gorge/internal/model" 10 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 11 | ) 12 | 13 | // getSortedKeys extracts and sorts endpoint keys from Statistics 14 | // Returns a sorted slice of endpoint strings 15 | func getSortedKeys(stats *customMiddleware.Statistics) []string { 16 | keys := []string{} 17 | for k := range stats.ConnectionsPerEndpoint { 18 | keys = append(keys, k) 19 | } 20 | sort.Strings(keys) 21 | return keys 22 | } 23 | 24 | // sortModules sorts a slice of modules alphabetically by name 25 | // Returns the sorted slice of modules 26 | func sortModules(modules []*gen.Module) []*gen.Module { 27 | sort.Slice(modules, func(i, j int) bool { 28 | return modules[i].Name < modules[j].Name 29 | }) 30 | return modules 31 | } 32 | 33 | // deps extracts module dependencies from metadata 34 | // Returns a slice of ModuleDependency or nil if parsing fails 35 | func deps(metadata map[string]interface{}) []model.ModuleDependency { 36 | var result model.ReleaseMetadata 37 | 38 | jsonStr, err := json.Marshal(metadata) 39 | if err != nil { 40 | return nil 41 | } 42 | 43 | err = json.Unmarshal(jsonStr, &result) 44 | if err != nil { 45 | return nil 46 | } 47 | 48 | return result.Dependencies 49 | } 50 | 51 | // normalize replaces forward slashes with hyphens in a string 52 | // Returns the normalized string 53 | func normalize(name string) string { 54 | return strings.Replace(name, "/", "-", 1) 55 | } 56 | -------------------------------------------------------------------------------- /internal/v3/ui/handlers.go: -------------------------------------------------------------------------------- 1 | package ui 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | 7 | "github.com/a-h/templ" 8 | "github.com/dadav/gorge/internal/log" 9 | customMiddleware "github.com/dadav/gorge/internal/middleware" 10 | "github.com/dadav/gorge/internal/v3/backend" 11 | "github.com/dadav/gorge/internal/v3/ui/components" 12 | gen "github.com/dadav/gorge/pkg/gen/v3/openapi" 13 | "github.com/go-chi/chi/v5" 14 | ) 15 | 16 | func handleError(w http.ResponseWriter, err error) { 17 | w.WriteHeader(http.StatusInternalServerError) 18 | log.Log.Error(err) 19 | } 20 | 21 | func IndexHandler(w http.ResponseWriter, r *http.Request) { 22 | modules, err := backend.ConfiguredBackend.GetAllModules() 23 | if err != nil { 24 | handleError(w, err) 25 | return 26 | } 27 | templ.Handler(components.Page("Gorge", components.SearchView("", modules))).ServeHTTP(w, r) 28 | } 29 | 30 | func SearchHandler(w http.ResponseWriter, r *http.Request) { 31 | query := strings.ToLower(r.URL.Query().Get("query")) 32 | modules, err := backend.ConfiguredBackend.GetAllModules() 33 | if err != nil { 34 | handleError(w, err) 35 | return 36 | } 37 | 38 | filtered := make([]*gen.Module, 0, len(modules)) 39 | queryTerms := strings.Fields(query) 40 | 41 | for _, module := range modules { 42 | matches := true 43 | for _, term := range queryTerms { 44 | if !strings.Contains(strings.ToLower(module.Name), term) && 45 | !strings.Contains(strings.ToLower(module.Owner.Username), term) && 46 | !strings.Contains(strings.ToLower(module.CurrentRelease.Version), term) { 47 | matches = false 48 | break 49 | } 50 | } 51 | if matches { 52 | filtered = append(filtered, module) 53 | } 54 | } 55 | 56 | templ.Handler(components.Page("Gorge", components.SearchView(query, filtered))).ServeHTTP(w, r) 57 | } 58 | 59 | func AuthorHandler(w http.ResponseWriter, r *http.Request) { 60 | authorSlug := chi.URLParam(r, "author") 61 | modules, err := backend.ConfiguredBackend.GetAllModules() 62 | if err != nil { 63 | handleError(w, err) 64 | return 65 | } 66 | 67 | authorModules := make(map[string][]*gen.Module) 68 | for _, module := range modules { 69 | authorModules[module.Owner.Slug] = append(authorModules[module.Owner.Slug], module) 70 | } 71 | 72 | if filtered, exists := authorModules[authorSlug]; exists && len(filtered) > 0 { 73 | templ.Handler(components.Page(authorSlug, components.AuthorView(filtered))).ServeHTTP(w, r) 74 | return 75 | } 76 | 77 | http.NotFound(w, r) 78 | } 79 | 80 | func ReleaseHandler(w http.ResponseWriter, r *http.Request) { 81 | moduleSlug := chi.URLParam(r, "module") 82 | version := chi.URLParam(r, "version") 83 | releases, err := backend.ConfiguredBackend.GetAllReleases() 84 | if err != nil { 85 | handleError(w, err) 86 | return 87 | } 88 | 89 | for _, release := range releases { 90 | if release.Module.Slug == moduleSlug && release.Version == version { 91 | templ.Handler(components.Page(release.Slug, components.ReleaseView(release))).ServeHTTP(w, r) 92 | return 93 | } 94 | } 95 | 96 | http.NotFound(w, r) 97 | } 98 | 99 | func ModuleHandler(w http.ResponseWriter, r *http.Request) { 100 | moduleSlug := chi.URLParam(r, "module") 101 | modules, err := backend.ConfiguredBackend.GetAllModules() 102 | if err != nil { 103 | w.WriteHeader(500) 104 | log.Log.Error(err) 105 | return 106 | } 107 | 108 | for _, module := range modules { 109 | if module.Slug == moduleSlug { 110 | templ.Handler(components.Page(module.Slug, components.ModuleView(module))).ServeHTTP(w, r) 111 | return 112 | } 113 | } 114 | 115 | http.NotFound(w, r) 116 | } 117 | 118 | func StatisticsHandler(stats *customMiddleware.Statistics) func(http.ResponseWriter, *http.Request) { 119 | return func(w http.ResponseWriter, r *http.Request) { 120 | stats.Mutex.Lock() 121 | defer stats.Mutex.Unlock() 122 | templ.Handler(components.Page("Statistics", components.StatisticsView(stats))).ServeHTTP(w, r) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /internal/v3/utils/path.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "regexp" 4 | 5 | // CheckModuleSlug validates if a module slug follows the required format: 6 | // - Must start with alphanumeric characters 7 | // - Must contain a hyphen or slash separator 8 | // - After separator, must start with a lowercase letter 9 | // - Can contain lowercase letters, numbers, and underscores after first letter 10 | // Example valid slugs: "myOrg/module", "company-mymodule" 11 | func CheckModuleSlug(slug string) bool { 12 | r, _ := regexp.Compile(`^[a-zA-Z0-9]+[-\/][a-z][a-z0-9_]*$`) 13 | return r.MatchString(slug) 14 | } 15 | 16 | // CheckReleaseSlug validates if a release slug follows the required format: 17 | // - Must start with a valid module slug (see above) 18 | // - Must contain another hyphen or slash separator 19 | // - Must end with a semantic version (X.Y.Z) 20 | // - May optionally include a pre-release or build metadata after version 21 | // Example valid slugs: "myOrg/module/1.2.3", "company-mymodule/2.0.0-beta.1" 22 | func CheckReleaseSlug(slug string) bool { 23 | r, _ := regexp.Compile(`^[a-zA-Z0-9]+[-\/][a-z][a-z0-9_]*[-\/][0-9]+\.[0-9]+\.[0-9]+(?:[\-+].+)?$`) 24 | return r.MatchString(slug) 25 | } 26 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadav/gorge/7e641fa55feceeaef9a63edd94d0bf49f4b2af05/logo.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2024 dadav 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package main 17 | 18 | import "github.com/dadav/gorge/cmd" 19 | 20 | func main() { 21 | cmd.Execute() 22 | } 23 | -------------------------------------------------------------------------------- /pkg/gen/v3/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator Ignore 2 | # Generated by openapi-generator https://github.com/openapitools/openapi-generator 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /pkg/gen/v3/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | .openapi-generator-ignore 2 | README.md 3 | api/openapi.yaml 4 | openapi/api.go 5 | openapi/api_module_operations.go 6 | openapi/api_module_operations_service.go 7 | openapi/api_release_operations.go 8 | openapi/api_release_operations_service.go 9 | openapi/api_search_filter_operations.go 10 | openapi/api_search_filter_operations_service.go 11 | openapi/api_user_operations.go 12 | openapi/api_user_operations_service.go 13 | openapi/error.go 14 | openapi/helpers.go 15 | openapi/impl.go 16 | openapi/logger.go 17 | openapi/model_add_release_request.go 18 | openapi/model_add_search_filter_409_response.go 19 | openapi/model_delete_user_search_filter_403_response.go 20 | openapi/model_deprecation_request.go 21 | openapi/model_deprecation_request_params.go 22 | openapi/model_get_file_400_response.go 23 | openapi/model_get_file_404_response.go 24 | openapi/model_get_modules_200_response.go 25 | openapi/model_get_modules_200_response_pagination.go 26 | openapi/model_get_release_plans_200_response.go 27 | openapi/model_get_release_plans_200_response_pagination.go 28 | openapi/model_get_releases_200_response.go 29 | openapi/model_get_releases_200_response_pagination.go 30 | openapi/model_get_user_search_filters_401_response.go 31 | openapi/model_get_users_200_response.go 32 | openapi/model_get_users_200_response_pagination.go 33 | openapi/model_module.go 34 | openapi/model_module_abbreviated.go 35 | openapi/model_module_current_release.go 36 | openapi/model_module_minimal.go 37 | openapi/model_module_owner.go 38 | openapi/model_module_superseded_by.go 39 | openapi/model_pagination.go 40 | openapi/model_release.go 41 | openapi/model_release_abbreviated.go 42 | openapi/model_release_minimal.go 43 | openapi/model_release_module.go 44 | openapi/model_release_plan.go 45 | openapi/model_release_plan_abbreviated.go 46 | openapi/model_release_plan_plan_metadata.go 47 | openapi/model_release_plan_plan_metadata_docstring.go 48 | openapi/model_release_plan_plan_metadata_docstring_tags_inner.go 49 | openapi/model_release_task.go 50 | openapi/model_search_filter.go 51 | openapi/model_search_filter_response.go 52 | openapi/model_user.go 53 | openapi/model_user_abbreviated.go 54 | openapi/routers.go 55 | -------------------------------------------------------------------------------- /pkg/gen/v3/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.3.0 -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/impl.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | // ImplResponse defines an implementation response with error code and the associated body 13 | type ImplResponse struct { 14 | Code int 15 | Body interface{} 16 | } 17 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/logger.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | import ( 13 | "log" 14 | "net/http" 15 | "time" 16 | ) 17 | 18 | func Logger(inner http.Handler, name string) http.Handler { 19 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 20 | start := time.Now() 21 | 22 | inner.ServeHTTP(w, r) 23 | 24 | log.Printf( 25 | "%s %s %s %s", 26 | r.Method, 27 | r.RequestURI, 28 | name, 29 | time.Since(start), 30 | ) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_add_release_request.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type AddReleaseRequest struct { 16 | 17 | File string `json:"file,omitempty"` 18 | } 19 | 20 | // AssertAddReleaseRequestRequired checks if the required fields are not zero-ed 21 | func AssertAddReleaseRequestRequired(obj AddReleaseRequest) error { 22 | return nil 23 | } 24 | 25 | // AssertAddReleaseRequestConstraints checks if the values respects the defined constraints 26 | func AssertAddReleaseRequestConstraints(obj AddReleaseRequest) error { 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_add_search_filter_409_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type AddSearchFilter409Response struct { 16 | 17 | Message string `json:"message,omitempty"` 18 | 19 | Errors []string `json:"errors,omitempty"` 20 | } 21 | 22 | // AssertAddSearchFilter409ResponseRequired checks if the required fields are not zero-ed 23 | func AssertAddSearchFilter409ResponseRequired(obj AddSearchFilter409Response) error { 24 | return nil 25 | } 26 | 27 | // AssertAddSearchFilter409ResponseConstraints checks if the values respects the defined constraints 28 | func AssertAddSearchFilter409ResponseConstraints(obj AddSearchFilter409Response) error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_delete_user_search_filter_403_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type DeleteUserSearchFilter403Response struct { 16 | 17 | Message string `json:"message,omitempty"` 18 | 19 | Errors []string `json:"errors,omitempty"` 20 | } 21 | 22 | // AssertDeleteUserSearchFilter403ResponseRequired checks if the required fields are not zero-ed 23 | func AssertDeleteUserSearchFilter403ResponseRequired(obj DeleteUserSearchFilter403Response) error { 24 | return nil 25 | } 26 | 27 | // AssertDeleteUserSearchFilter403ResponseConstraints checks if the values respects the defined constraints 28 | func AssertDeleteUserSearchFilter403ResponseConstraints(obj DeleteUserSearchFilter403Response) error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_deprecation_request.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type DeprecationRequest struct { 16 | 17 | // Action to take on resource. 'deprecate' is currently the only valid option. 18 | Action string `json:"action,omitempty"` 19 | 20 | Params *DeprecationRequestParams `json:"params,omitempty"` 21 | } 22 | 23 | // AssertDeprecationRequestRequired checks if the required fields are not zero-ed 24 | func AssertDeprecationRequestRequired(obj DeprecationRequest) error { 25 | if obj.Params != nil { 26 | if err := AssertDeprecationRequestParamsRequired(*obj.Params); err != nil { 27 | return err 28 | } 29 | } 30 | return nil 31 | } 32 | 33 | // AssertDeprecationRequestConstraints checks if the values respects the defined constraints 34 | func AssertDeprecationRequestConstraints(obj DeprecationRequest) error { 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_deprecation_request_params.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type DeprecationRequestParams struct { 16 | 17 | // Reason for deprecation 18 | Reason *string `json:"reason,omitempty"` 19 | 20 | // Slug identifying a replacement Module. Accepts legacy (case-sensitive) module naming. 21 | ReplacementSlug *string `json:"replacement_slug,omitempty"` 22 | } 23 | 24 | // AssertDeprecationRequestParamsRequired checks if the required fields are not zero-ed 25 | func AssertDeprecationRequestParamsRequired(obj DeprecationRequestParams) error { 26 | return nil 27 | } 28 | 29 | // AssertDeprecationRequestParamsConstraints checks if the values respects the defined constraints 30 | func AssertDeprecationRequestParamsConstraints(obj DeprecationRequestParams) error { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_file_400_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetFile400Response struct { 16 | 17 | Message string `json:"message,omitempty"` 18 | 19 | Errors []string `json:"errors,omitempty"` 20 | } 21 | 22 | // AssertGetFile400ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetFile400ResponseRequired(obj GetFile400Response) error { 24 | return nil 25 | } 26 | 27 | // AssertGetFile400ResponseConstraints checks if the values respects the defined constraints 28 | func AssertGetFile400ResponseConstraints(obj GetFile400Response) error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_file_404_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetFile404Response struct { 16 | 17 | Message string `json:"message,omitempty"` 18 | 19 | Errors []string `json:"errors,omitempty"` 20 | } 21 | 22 | // AssertGetFile404ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetFile404ResponseRequired(obj GetFile404Response) error { 24 | return nil 25 | } 26 | 27 | // AssertGetFile404ResponseConstraints checks if the values respects the defined constraints 28 | func AssertGetFile404ResponseConstraints(obj GetFile404Response) error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_modules_200_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetModules200Response struct { 16 | 17 | Pagination GetModules200ResponsePagination `json:"pagination,omitempty"` 18 | 19 | Results []Module `json:"results,omitempty"` 20 | } 21 | 22 | // AssertGetModules200ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetModules200ResponseRequired(obj GetModules200Response) error { 24 | if err := AssertGetModules200ResponsePaginationRequired(obj.Pagination); err != nil { 25 | return err 26 | } 27 | for _, el := range obj.Results { 28 | if err := AssertModuleRequired(el); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | // AssertGetModules200ResponseConstraints checks if the values respects the defined constraints 36 | func AssertGetModules200ResponseConstraints(obj GetModules200Response) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_release_plans_200_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetReleasePlans200Response struct { 16 | 17 | Pagination GetReleasePlans200ResponsePagination `json:"pagination,omitempty"` 18 | 19 | Results []ReleasePlan `json:"results,omitempty"` 20 | } 21 | 22 | // AssertGetReleasePlans200ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetReleasePlans200ResponseRequired(obj GetReleasePlans200Response) error { 24 | if err := AssertGetReleasePlans200ResponsePaginationRequired(obj.Pagination); err != nil { 25 | return err 26 | } 27 | for _, el := range obj.Results { 28 | if err := AssertReleasePlanRequired(el); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | // AssertGetReleasePlans200ResponseConstraints checks if the values respects the defined constraints 36 | func AssertGetReleasePlans200ResponseConstraints(obj GetReleasePlans200Response) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_releases_200_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetReleases200Response struct { 16 | 17 | Pagination GetReleases200ResponsePagination `json:"pagination,omitempty"` 18 | 19 | Results []Release `json:"results,omitempty"` 20 | } 21 | 22 | // AssertGetReleases200ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetReleases200ResponseRequired(obj GetReleases200Response) error { 24 | if err := AssertGetReleases200ResponsePaginationRequired(obj.Pagination); err != nil { 25 | return err 26 | } 27 | for _, el := range obj.Results { 28 | if err := AssertReleaseRequired(el); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | // AssertGetReleases200ResponseConstraints checks if the values respects the defined constraints 36 | func AssertGetReleases200ResponseConstraints(obj GetReleases200Response) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_user_search_filters_401_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetUserSearchFilters401Response struct { 16 | 17 | Message string `json:"message,omitempty"` 18 | 19 | Errors []string `json:"errors,omitempty"` 20 | } 21 | 22 | // AssertGetUserSearchFilters401ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetUserSearchFilters401ResponseRequired(obj GetUserSearchFilters401Response) error { 24 | return nil 25 | } 26 | 27 | // AssertGetUserSearchFilters401ResponseConstraints checks if the values respects the defined constraints 28 | func AssertGetUserSearchFilters401ResponseConstraints(obj GetUserSearchFilters401Response) error { 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_get_users_200_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type GetUsers200Response struct { 16 | 17 | Pagination GetUsers200ResponsePagination `json:"pagination,omitempty"` 18 | 19 | Results []User `json:"results,omitempty"` 20 | } 21 | 22 | // AssertGetUsers200ResponseRequired checks if the required fields are not zero-ed 23 | func AssertGetUsers200ResponseRequired(obj GetUsers200Response) error { 24 | if err := AssertGetUsers200ResponsePaginationRequired(obj.Pagination); err != nil { 25 | return err 26 | } 27 | for _, el := range obj.Results { 28 | if err := AssertUserRequired(el); err != nil { 29 | return err 30 | } 31 | } 32 | return nil 33 | } 34 | 35 | // AssertGetUsers200ResponseConstraints checks if the values respects the defined constraints 36 | func AssertGetUsers200ResponseConstraints(obj GetUsers200Response) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_module_minimal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ModuleMinimal struct { 16 | 17 | // Relative URL for this Module resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this Module resource 21 | Slug string `json:"slug,omitempty"` 22 | } 23 | 24 | // AssertModuleMinimalRequired checks if the required fields are not zero-ed 25 | func AssertModuleMinimalRequired(obj ModuleMinimal) error { 26 | return nil 27 | } 28 | 29 | // AssertModuleMinimalConstraints checks if the values respects the defined constraints 30 | func AssertModuleMinimalConstraints(obj ModuleMinimal) error { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_module_owner.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ModuleOwner struct { 16 | 17 | // Relative URL for this User resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this User resource 21 | Slug string `json:"slug,omitempty"` 22 | 23 | // Username for this User resource 24 | Username string `json:"username,omitempty"` 25 | 26 | // Gravatar ID, learn more at [https://gravatar.com/]() 27 | GravatarId string `json:"gravatar_id,omitempty"` 28 | } 29 | 30 | // AssertModuleOwnerRequired checks if the required fields are not zero-ed 31 | func AssertModuleOwnerRequired(obj ModuleOwner) error { 32 | return nil 33 | } 34 | 35 | // AssertModuleOwnerConstraints checks if the values respects the defined constraints 36 | func AssertModuleOwnerConstraints(obj ModuleOwner) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_module_superseded_by.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ModuleSupersededBy struct { 16 | 17 | // Relative URL for this Module resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this Module resource 21 | Slug string `json:"slug,omitempty"` 22 | } 23 | 24 | // AssertModuleSupersededByRequired checks if the required fields are not zero-ed 25 | func AssertModuleSupersededByRequired(obj ModuleSupersededBy) error { 26 | return nil 27 | } 28 | 29 | // AssertModuleSupersededByConstraints checks if the values respects the defined constraints 30 | func AssertModuleSupersededByConstraints(obj ModuleSupersededBy) error { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_release_minimal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ReleaseMinimal struct { 16 | 17 | // Relative URL for this Release resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this Release resource 21 | Slug string `json:"slug,omitempty"` 22 | 23 | // Relative or absolute URL to download this release's tarball 24 | FileUri string `json:"file_uri,omitempty"` 25 | } 26 | 27 | // AssertReleaseMinimalRequired checks if the required fields are not zero-ed 28 | func AssertReleaseMinimalRequired(obj ReleaseMinimal) error { 29 | return nil 30 | } 31 | 32 | // AssertReleaseMinimalConstraints checks if the values respects the defined constraints 33 | func AssertReleaseMinimalConstraints(obj ReleaseMinimal) error { 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_release_module.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ReleaseModule struct { 16 | 17 | // Relative URL for this Module resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this Module resource 21 | Slug string `json:"slug,omitempty"` 22 | 23 | // Base name of this module (without username/namespace) 24 | Name string `json:"name,omitempty"` 25 | 26 | // Date and time this Module resource was marked as deprecated by the owner 27 | DeprecatedAt *string `json:"deprecated_at,omitempty"` 28 | 29 | Owner ModuleOwner `json:"owner,omitempty"` 30 | } 31 | 32 | // AssertReleaseModuleRequired checks if the required fields are not zero-ed 33 | func AssertReleaseModuleRequired(obj ReleaseModule) error { 34 | if err := AssertModuleOwnerRequired(obj.Owner); err != nil { 35 | return err 36 | } 37 | return nil 38 | } 39 | 40 | // AssertReleaseModuleConstraints checks if the values respects the defined constraints 41 | func AssertReleaseModuleConstraints(obj ReleaseModule) error { 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_release_plan.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ReleasePlan struct { 16 | 17 | // Relative URL for this Plan resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // The name of the plan, including the module name 21 | Name string `json:"name,omitempty"` 22 | 23 | // Path to this Plan within the module's file structure 24 | Filename string `json:"filename,omitempty"` 25 | 26 | PlanMetadata ReleasePlanPlanMetadata `json:"plan_metadata,omitempty"` 27 | 28 | // Whether this plan is private 29 | Private bool `json:"private,omitempty"` 30 | } 31 | 32 | // AssertReleasePlanRequired checks if the required fields are not zero-ed 33 | func AssertReleasePlanRequired(obj ReleasePlan) error { 34 | if err := AssertReleasePlanPlanMetadataRequired(obj.PlanMetadata); err != nil { 35 | return err 36 | } 37 | return nil 38 | } 39 | 40 | // AssertReleasePlanConstraints checks if the values respects the defined constraints 41 | func AssertReleasePlanConstraints(obj ReleasePlan) error { 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_release_plan_abbreviated.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type ReleasePlanAbbreviated struct { 16 | 17 | // URL path to the full metadata for this plan 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // The name of the plan, including the module name 21 | Name string `json:"name,omitempty"` 22 | 23 | // Whether this plan is private 24 | Private bool `json:"private,omitempty"` 25 | } 26 | 27 | // AssertReleasePlanAbbreviatedRequired checks if the required fields are not zero-ed 28 | func AssertReleasePlanAbbreviatedRequired(obj ReleasePlanAbbreviated) error { 29 | return nil 30 | } 31 | 32 | // AssertReleasePlanAbbreviatedConstraints checks if the values respects the defined constraints 33 | func AssertReleasePlanAbbreviatedConstraints(obj ReleasePlanAbbreviated) error { 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_search_filter.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type SearchFilter struct { 16 | 17 | // The unique identifier for the search filter. 18 | Id int32 `json:"id,omitempty"` 19 | 20 | // The hash definining the search filter criteria. 21 | Filter map[string]interface{} `json:"filter,omitempty"` 22 | 23 | // Indicates whether the search filter is active. 24 | Active bool `json:"active,omitempty"` 25 | 26 | // The timestamp indicating when the search filter was created. 27 | CreatedAt string `json:"created_at,omitempty"` 28 | } 29 | 30 | // AssertSearchFilterRequired checks if the required fields are not zero-ed 31 | func AssertSearchFilterRequired(obj SearchFilter) error { 32 | return nil 33 | } 34 | 35 | // AssertSearchFilterConstraints checks if the values respects the defined constraints 36 | func AssertSearchFilterConstraints(obj SearchFilter) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_search_filter_response.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type SearchFilterResponse struct { 16 | 17 | // The array of user search filter. 18 | UserSearchFilters []SearchFilter `json:"user_search_filters,omitempty"` 19 | } 20 | 21 | // AssertSearchFilterResponseRequired checks if the required fields are not zero-ed 22 | func AssertSearchFilterResponseRequired(obj SearchFilterResponse) error { 23 | for _, el := range obj.UserSearchFilters { 24 | if err := AssertSearchFilterRequired(el); err != nil { 25 | return err 26 | } 27 | } 28 | return nil 29 | } 30 | 31 | // AssertSearchFilterResponseConstraints checks if the values respects the defined constraints 32 | func AssertSearchFilterResponseConstraints(obj SearchFilterResponse) error { 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /pkg/gen/v3/openapi/model_user_abbreviated.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Puppet Forge v3 API 3 | * 4 | * ## Introduction The Puppet Forge API (hereafter referred to as the Forge API) provides quick access to all the data on the Puppet Forge via a RESTful interface. Using the Forge API, you can write scripts and tools that interact with the Puppet Forge website. The Forge API's current version is `v3`. It is considered regression-stable, meaning that the returned data is guaranteed to include the fields described in the schemas on this page; however, additional data might be added in the future and clients must ignore any properties they do not recognize. ## OpenAPI Specification The Puppet Forge v3 API is described by an [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md) formatted specification file. The most up-to-date version of this specification file can be accessed at [https://forgeapi.puppet.com/v3/openapi.json](/v3/openapi.json). ## Features * The API is accessed over HTTPS via either the `forgeapi.puppet.com` (IPv4 or IPv6). All data is returned in JSON format. * Blank fields are included as `null`. * Nested resources may use an abbreviated representation. A link to the full representation for the resource is always included. * All timestamps in JSON responses are returned in ISO 8601 format: `YYYY-MM-DD HH:MM:SS ±HHMM`. * The HTTP response headers include caching hints for conditional requests. ## Concepts and Terminology * **Module**: Modules are self-contained bundles of code and data with a specific directory structure. Modules are identified by a combination of the author's username and the module's name, separated by a hyphen. For example: `puppetlabs-apache` * **Release**: A single, specific version of a module is called a Release. Releases are identified by a combination of the module identifier (see above) and the Release version, separated by a hyphen. For example: `puppetlabs-apache-4.0.0` ## Errors The Puppet Forge API follows [RFC 2616](https://tools.ietf.org/html/rfc2616) and [RFC 6585](https://tools.ietf.org/html/rfc6585). Error responses are served with a `4xx` or `5xx` status code, and are sent as a JSON document with a content type of `application/json`. The error document contains the following top-level keys and values: * `message`: a string value that summarizes the problem * `errors`: a list (array) of strings containing additional details describing the underlying cause(s) of the failure An example error response is shown below: ```json { \"message\": \"400 Bad Request\", \"errors\": [ \"Cannot parse request body as JSON\" ] } ``` ## User-Agent Required All API requests must include a valid `User-Agent` header. Requests with no `User-Agent` header will be rejected. The `User-Agent` header helps identify your application or library, so we can communicate with you if necessary. If your use of the API is informal or personal, we recommend using your username as the value for the `User-Agent` header. User-Agent headers are a list of one or more product descriptions, generally taking this form: ``` / (comments) ``` For example, the following are all useful User-Agent values: ``` MyApplication/0.0.0 Her/0.6.8 Faraday/0.8.8 Ruby/1.9.3-p194 (i386-linux) My-Library-Name/1.2.4 myusername ``` ## Hostname Configuration Most tools that interact with the Forge API allow specification of the hostname to use. You can configure a few common tools to use a specified hostname as follows: For **Puppet Enterprise** users, in [r10k](https://puppet.com/docs/pe/latest/r10k_customize_config.html#r10k_configuring_forge_settings) or [Code Manager](https://puppet.com/docs/pe/latest/code_mgr_customizing.html#config_forge_settings), specify `forge_settings` in Hiera: ``` pe_r10k::forge_settings: baseurl: 'https://forgeapi.puppet.com' ``` or ``` puppet_enterprise::master::code_manager::forge_settings: baseurl: 'https://forgeapi.puppet.com' ```
If you are an **open source Puppet** user using r10k, you'll need to [edit your r10k.yaml directly](https://github.com/puppetlabs/r10k/blob/main/doc/dynamic-environments/configuration.mkd#forge): ``` forge: baseurl: 'https://forgeapi.puppet.com' ``` or set the appropriate class param for the [open source r10k module](https://forge.puppet.com/puppet/r10k#forge_settings): ``` $forge_settings = { 'baseurl' => 'https://forgeapi.puppet.com', } ```
In [**Bolt**](https://puppet.com/docs/bolt/latest/bolt_installing_modules.html#install-forge-modules-from-an-alternate-forge), set a `baseurl` for the Forge in `bolt-project.yaml`: ``` module-install: forge: baseurl: https://forgeapi.puppet.com ```
Using `puppet config`: ``` $ puppet config set module_repository https://forgeapi.puppet.com ``` 5 | * 6 | * API version: 29 7 | * Generated by: OpenAPI Generator (https://openapi-generator.tech) 8 | */ 9 | 10 | package gorge 11 | 12 | 13 | 14 | 15 | type UserAbbreviated struct { 16 | 17 | // Relative URL for this User resource 18 | Uri string `json:"uri,omitempty"` 19 | 20 | // Unique textual identifier for this User resource 21 | Slug string `json:"slug,omitempty"` 22 | 23 | // Username for this User resource 24 | Username string `json:"username,omitempty"` 25 | 26 | // Gravatar ID, learn more at [https://gravatar.com/]() 27 | GravatarId string `json:"gravatar_id,omitempty"` 28 | } 29 | 30 | // AssertUserAbbreviatedRequired checks if the required fields are not zero-ed 31 | func AssertUserAbbreviatedRequired(obj UserAbbreviated) error { 32 | return nil 33 | } 34 | 35 | // AssertUserAbbreviatedConstraints checks if the values respects the defined constraints 36 | func AssertUserAbbreviatedConstraints(obj UserAbbreviated) error { 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:best-practices", "schedule:earlyMondays"], 4 | "bumpVersion": "patch", 5 | "prHourlyLimit": 4 6 | } 7 | --------------------------------------------------------------------------------