mirror of https://github.com/helm/chartmuseum.git
Compare commits
29 Commits
Author | SHA1 | Date |
---|---|---|
|
fce57c0052 | |
|
ad1d7c62f6 | |
|
e10e46afa9 | |
|
45965f2ea8 | |
|
315db247a8 | |
|
d9eaedb134 | |
|
96c95b967c | |
|
dee42f20db | |
|
9a7e3508d5 | |
|
e55647c517 | |
|
50846585f5 | |
|
7908b93b3d | |
|
5e32c8d336 | |
|
8795e9930a | |
|
0a4fbd9ae3 | |
|
574fd1cbef | |
|
bea8a5db8e | |
|
aaf4b1a549 | |
|
96f70483ba | |
|
bc761e801b | |
|
00ba7520f5 | |
|
dfd85117db | |
|
a090682770 | |
|
60c334dee3 | |
|
157f397ade | |
|
13758afdf0 | |
|
14f30113aa | |
|
5e41c5a188 | |
|
90e47f6336 |
|
@ -14,7 +14,7 @@ jobs:
|
|||
- name: setup go environment
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.23'
|
||||
- name: download dependencies
|
||||
run: make bootstrap
|
||||
- name: run unit tests
|
||||
|
|
|
@ -15,12 +15,16 @@ jobs:
|
|||
packages: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Reclaim disk space
|
||||
run: |
|
||||
sudo rm -rf /usr/local/lib/android
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: setup go environment
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '1.20'
|
||||
go-version: '1.23'
|
||||
- name: download dependencies
|
||||
run: make bootstrap
|
||||
- name: run unit tests
|
||||
|
@ -73,7 +77,9 @@ jobs:
|
|||
- name: Install Kubernetes SBOM Tool
|
||||
uses: puerco/bom-installer@aa0837e37b6965b5fc50adfad0683ec3c0a2c2c4
|
||||
- name: Install sigstore cosign
|
||||
uses: sigstore/cosign-installer@v3.1.1
|
||||
uses: sigstore/cosign-installer@main
|
||||
with:
|
||||
cosign-version: 'v2.2.4'
|
||||
- name: Release artifacts (includes SBOM and signatures)
|
||||
id: release-artifacts
|
||||
env:
|
||||
|
|
5
Makefile
5
Makefile
|
@ -1,4 +1,5 @@
|
|||
VERSION ?= 0.16.1
|
||||
# TODO(cbuto): Pull from git tag to avoid needing to bump this prior to releasing
|
||||
VERSION ?= 0.16.3
|
||||
REVISION := $(shell git rev-parse --short HEAD;)
|
||||
|
||||
BINDIR := $(CURDIR)/bin
|
||||
|
@ -230,5 +231,3 @@ lint:
|
|||
echo "golangci-lint is not installed, please install it from https://golangci-lint.run/usage/install/"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ docker run --rm -it \
|
|||
-e STORAGE=local \
|
||||
-e STORAGE_LOCAL_ROOTDIR=/charts \
|
||||
-v $(pwd)/charts:/charts \
|
||||
ghcr.io/helm/chartmuseum:v0.16.1
|
||||
ghcr.io/helm/chartmuseum:v0.16.3
|
||||
```
|
||||
|
||||
Example usage (S3):
|
||||
|
@ -485,7 +485,7 @@ docker run --rm -it \
|
|||
-e STORAGE_AMAZON_PREFIX="" \
|
||||
-e STORAGE_AMAZON_REGION="us-east-1" \
|
||||
-v ~/.aws:/home/chartmuseum/.aws:ro \
|
||||
ghcr.io/helm/chartmuseum:v0.16.1
|
||||
ghcr.io/helm/chartmuseum:v0.16.3
|
||||
```
|
||||
|
||||
### Helm Chart
|
||||
|
|
|
@ -119,6 +119,7 @@ func cliHandler(c *cli.Context) {
|
|||
WebTemplatePath: conf.GetString("web-template-path"),
|
||||
ArtifactHubRepoID: conf.GetStringMapString("artifact-hub-repo-id"),
|
||||
AlwaysRegenerateIndex: conf.GetBool("always-regenerate-chart-index"),
|
||||
JSONIndex: conf.GetBool("json-index"),
|
||||
}
|
||||
|
||||
server, err := newServer(options)
|
||||
|
|
234
go.mod
234
go.mod
|
@ -1,190 +1,200 @@
|
|||
module helm.sh/chartmuseum
|
||||
|
||||
go 1.20
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible
|
||||
github.com/chartmuseum/auth v0.5.0
|
||||
github.com/chartmuseum/storage v0.14.1
|
||||
github.com/chartmuseum/storage v0.16.0
|
||||
github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/prometheus/client_golang v1.20.4
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/urfave/cli v1.22.14
|
||||
github.com/zsais/go-gin-prometheus v0.1.0
|
||||
go.uber.org/zap v1.24.0
|
||||
helm.sh/helm/v3 v3.12.3
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/urfave/cli v1.22.15
|
||||
go.uber.org/zap v1.27.0
|
||||
helm.sh/helm/v3 v3.17.3
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.4 // indirect
|
||||
cloud.google.com/go/compute v1.21.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.1 // indirect
|
||||
cloud.google.com/go v0.112.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/storage v1.36.0 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.4 // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.4+incompatible // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.288 // indirect
|
||||
github.com/aws/aws-sdk-go v1.47.11 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.123 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/clbanning/mxj v1.8.4 // indirect
|
||||
github.com/containerd/containerd v1.7.11 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/containerd/containerd v1.7.27 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/cli v23.0.3+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker v23.0.3+incompatible // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/cli v25.0.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v25.0.6+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/gomodule/redigo v1.8.9 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gophercloud/gophercloud v0.25.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.16.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.3.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/gomega v1.27.8 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/cobra v1.6.1 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.35 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/xlab/treeprint v1.1.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
github.com/yuin/gopher-lua v1.1.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.16 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.16 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
|
||||
go.opentelemetry.io/otel v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/goleak v1.1.12 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.10.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/term v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.126.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/grpc v1.58.3 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
|
||||
go.opentelemetry.io/otel v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.28.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.28.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/term v0.30.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
google.golang.org/api v0.155.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect
|
||||
google.golang.org/grpc v1.65.0 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.27.3 // indirect
|
||||
k8s.io/apimachinery v0.27.3 // indirect
|
||||
k8s.io/cli-runtime v0.27.3 // indirect
|
||||
k8s.io/client-go v0.27.3 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
|
||||
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect
|
||||
oras.land/oras-go v1.2.3 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/kustomize/api v0.13.2 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
k8s.io/api v0.32.2 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.32.2 // indirect
|
||||
k8s.io/apimachinery v0.32.2 // indirect
|
||||
k8s.io/cli-runtime v0.32.2 // indirect
|
||||
k8s.io/client-go v0.32.2 // indirect
|
||||
k8s.io/component-base v0.32.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
|
||||
k8s.io/kubectl v0.32.2 // indirect
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
|
||||
oras.land/oras-go v1.2.5 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.18.0 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
|
||||
)
|
||||
|
|
|
@ -237,61 +237,39 @@
|
|||
},
|
||||
"gevent": {
|
||||
"hashes": [
|
||||
"sha256:018f93de7d5318d2fb440f846839a4464738468c3476d5c9cf7da45bb71c18bd",
|
||||
"sha256:0d581f22a5be6281b11ad6309b38b18f0638cf896931223cbaa5adb904826ef6",
|
||||
"sha256:1472012493ca1fac103f700d309cb6ef7964dcdb9c788d1768266e77712f5e49",
|
||||
"sha256:172caa66273315f283e90a315921902cb6549762bdcb0587fd60cb712a9d6263",
|
||||
"sha256:17b68f4c9e20e47ad49fe797f37f91d5bbeace8765ce2707f979a8d4ec197e4d",
|
||||
"sha256:1ca01da176ee37b3527a2702f7d40dbc9ffb8cfc7be5a03bfa4f9eec45e55c46",
|
||||
"sha256:1d543c9407a1e4bca11a8932916988cfb16de00366de5bf7bc9e7a3f61e60b18",
|
||||
"sha256:1e1286a76f15b5e15f1e898731d50529e249529095a032453f2c101af3fde71c",
|
||||
"sha256:1e955238f59b2947631c9782a713280dd75884e40e455313b5b6bbc20b92ff73",
|
||||
"sha256:1f001cac0ba8da76abfeb392a3057f81fab3d67cc916c7df8ea977a44a2cc989",
|
||||
"sha256:1ff3796692dff50fec2f381b9152438b221335f557c4f9b811f7ded51b7a25a1",
|
||||
"sha256:2929377c8ebfb6f4d868d161cd8de2ea6b9f6c7a5fcd4f78bcd537319c16190b",
|
||||
"sha256:319d8b1699b7b8134de66d656cd739b308ab9c45ace14d60ae44de7775b456c9",
|
||||
"sha256:323b207b281ba0405fea042067fa1a61662e5ac0d574ede4ebbda03efd20c350",
|
||||
"sha256:3b7eae8a0653ba95a224faaddf629a913ace408edb67384d3117acf42d7dcf89",
|
||||
"sha256:4114f0f439f0b547bb6f1d474fee99ddb46736944ad2207cef3771828f6aa358",
|
||||
"sha256:4197d423e198265eef39a0dea286ef389da9148e070310f34455ecee8172c391",
|
||||
"sha256:494c7f29e94df9a1c3157d67bb7edfa32a46eed786e04d9ee68d39f375e30001",
|
||||
"sha256:4e2f008c82dc54ec94f4de12ca6feea60e419babb48ec145456907ae61625aa4",
|
||||
"sha256:53ee7f170ed42c7561fe8aff5d381dc9a4124694e70580d0c02fba6aafc0ea37",
|
||||
"sha256:54f4bfd74c178351a4a05c5c7df6f8a0a279ff6f392b57608ce0e83c768207f9",
|
||||
"sha256:58898dbabb5b11e4d0192aae165ad286dc6742c543e1be9d30dc82753547c508",
|
||||
"sha256:59b47e81b399d49a5622f0f503c59f1ce57b7705306ea0196818951dfc2f36c8",
|
||||
"sha256:5aa99e4882a9e909b4756ee799c6fa0f79eb0542779fad4cc60efa23ec1b2aa8",
|
||||
"sha256:6c04ee32c11e9fcee47c1b431834878dc987a7a2cc4fe126ddcae3bad723ce89",
|
||||
"sha256:84c517e33ed604fa06b7d756dc0171169cc12f7fdd68eb7b17708a62eebf4516",
|
||||
"sha256:8729129edef2637a8084258cb9ec4e4d5ca45d97ac77aa7a6ff19ccb530ab731",
|
||||
"sha256:877abdb3a669576b1d51ce6a49b7260b2a96f6b2424eb93287e779a3219d20ba",
|
||||
"sha256:8c192d2073e558e241f0b592c1e2b34127a4481a5be240cad4796533b88b1a98",
|
||||
"sha256:8f2477e7b0a903a01485c55bacf2089110e5f767014967ba4b287ff390ae2638",
|
||||
"sha256:96c56c280e3c43cfd075efd10b250350ed5ffd3c1514ec99a080b1b92d7c8374",
|
||||
"sha256:97cd42382421779f5d82ec5007199e8a84aa288114975429e4fd0a98f2290f10",
|
||||
"sha256:98bc510e80f45486ef5b806a1c305e0e89f0430688c14984b0dbdec03331f48b",
|
||||
"sha256:990d7069f14dc40674e0d5cb43c68fd3bad8337048613b9bb94a0c4180ffc176",
|
||||
"sha256:9d85574eb729f981fea9a78998725a06292d90a3ed50ddca74530c3148c0be41",
|
||||
"sha256:a2237451c721a0f874ef89dbb4af4fdc172b76a964befaa69deb15b8fff10f49",
|
||||
"sha256:a47a4e77e2bc668856aad92a0b8de7ee10768258d93cd03968e6c7ba2e832f76",
|
||||
"sha256:a5488eba6a568b4d23c072113da4fc0feb1b5f5ede7381656dc913e0d82204e2",
|
||||
"sha256:ae90226074a6089371a95f20288431cd4b3f6b0b096856afd862e4ac9510cddd",
|
||||
"sha256:b43d500d7d3c0e03070dee813335bb5315215aa1cf6a04c61093dfdd718640b3",
|
||||
"sha256:b6c144e08dfad4106effc043a026e5d0c0eff6ad031904c70bf5090c63f3a6a7",
|
||||
"sha256:d21ad79cca234cdbfa249e727500b0ddcbc7adfff6614a96e6eaa49faca3e4f2",
|
||||
"sha256:d82081656a5b9a94d37c718c8646c757e1617e389cdc533ea5e6a6f0b8b78545",
|
||||
"sha256:da4183f0b9d9a1e25e1758099220d32c51cc2c6340ee0dea3fd236b2b37598e4",
|
||||
"sha256:db562a8519838bddad0c439a2b12246bab539dd50e299ea7ff3644274a33b6a5",
|
||||
"sha256:ddaa3e310a8f1a45b5c42cf50b54c31003a3028e7d4e085059090ea0e7a5fddd",
|
||||
"sha256:ed7f16613eebf892a6a744d7a4a8f345bc6f066a0ff3b413e2479f9c0a180193",
|
||||
"sha256:efc003b6c1481165af61f0aeac248e0a9ac8d880bb3acbe469b448674b2d5281",
|
||||
"sha256:f01c9adbcb605364694b11dcd0542ec468a29ac7aba2fb5665dc6caf17ba4d7e",
|
||||
"sha256:f23d0997149a816a2a9045af29c66f67f405a221745b34cefeac5769ed451db8",
|
||||
"sha256:f3329bedbba4d3146ae58c667e0f9ac1e6f1e1e6340c7593976cdc60aa7d1a47",
|
||||
"sha256:f7ed2346eb9dc4344f9cb0d7963ce5b74fe16fdd031a2809bb6c2b6eba7ebcd5"
|
||||
"sha256:03d7452ec45c71ef84cacbf199dac582af2948fb37c638aa6e7232fe5c2840f1",
|
||||
"sha256:06a927940f9348b504888f93c8d85c2d8e2277ffd2105734148c0082ade17c20",
|
||||
"sha256:117904bdb139adeb3378a0631e81fc5939b54edce16ddf21288bde111ab31d47",
|
||||
"sha256:1578b5c6da4e88f5cade5682b13635d17231ade6c549d8498cc95776954675c4",
|
||||
"sha256:169784ef1594ddac0a773e85e5f996f6f8512abdbe248bff16ed8a22fafecadb",
|
||||
"sha256:17abeca1a8b61a0ce135127f8328265a317efaa3eda047199d65129ca68f0268",
|
||||
"sha256:1b9ff212cddf245d44651600970c5370c4168f710d4856d8b2350d734dfff1a6",
|
||||
"sha256:1ecd70495749ba1ece8e312e41e98d3371f5aa1e98922b47b3635c8263157938",
|
||||
"sha256:259438ec75b31b199d99941294e50f705d92d20d59578244a882a57c2f0f52b3",
|
||||
"sha256:2894d82111ed27b7f80dcbf8c713bb9c9c2c7e8890606cf548f6320fb2ae328f",
|
||||
"sha256:291c380fd708c5e04d63fcb8427da21600fda202ffe14ba59a454efd1715f8d5",
|
||||
"sha256:2bb65683df8a0a1427d42985158cee7dad8a3211247d5824302e276d9fd5bf65",
|
||||
"sha256:3778609919477ae6eccbf3b10308015f5620c428dbf0dbc6cbeb8a135c9d603a",
|
||||
"sha256:41199f10877f368822058b47aca3276e5a4c453e2c4df814a44f23c1bf059488",
|
||||
"sha256:436d0e9c1185b15f0204f7e2a687af2fc5307b1fed8ce011b86732ad53edc136",
|
||||
"sha256:5afcf6402981f33c84567e6a0a8dcf05e52e8c0b03d80b699644c5f251221e02",
|
||||
"sha256:70bd1e7a6f571837beb190e3a330f289d10ba4d84fa980ffe778b97fb887455c",
|
||||
"sha256:863a244311e986e924baa1516d821c37fcdb4e091e42f86f9d17d13323893c6d",
|
||||
"sha256:91e1e96d50dc4a296dce77b9e28c29a7401fbaca6809989b2029266db6172967",
|
||||
"sha256:951d95f1066fb84f661f2bb2c1d6423855a63922abf3e5bd1001711cfb1d8f38",
|
||||
"sha256:96a3ce33e77277995436656e6f7712f4dcbe9dafa527f245ebbe3de44fd3d4bb",
|
||||
"sha256:9b6eecefb35ceaa33693b971d18e98bfc7e63c9488f1b83eddedb8087a567066",
|
||||
"sha256:b6179e5419044f8e49ab1fd2165391ffd94071362e03a04d2e499a64b619e105",
|
||||
"sha256:bb645e9f68cb4b009d667507195e07314c594b2dac962ae797bd05bccd4076eb",
|
||||
"sha256:d55cf22d6b29593d256bad9fade978fbdc998d6f3bf3aa3399a81feaa91b5a86",
|
||||
"sha256:d76871f16df200c9454d3f9695b6cd97e7b80102fdf3e4b69b1e2900f9bd0eee",
|
||||
"sha256:e9e3f81cc36eb623e8716515bd7e28f50ccca5fd930ba493275e60d5fbc69786",
|
||||
"sha256:f44f1d3a05ce1d041d514b8151aec82e4649e5f8f6e2d837eb9bfc2607d7b64d",
|
||||
"sha256:faad7ed513672083eabe1e45d1dbfbbcd7bde9c0da6ef3598e975128c8aee427"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||
"version": "==22.10.2"
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==23.9.0"
|
||||
},
|
||||
"geventhttpclient": {
|
||||
"hashes": [
|
||||
|
@ -390,69 +368,67 @@
|
|||
},
|
||||
"greenlet": {
|
||||
"hashes": [
|
||||
"sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a",
|
||||
"sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a",
|
||||
"sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43",
|
||||
"sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33",
|
||||
"sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8",
|
||||
"sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088",
|
||||
"sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca",
|
||||
"sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343",
|
||||
"sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645",
|
||||
"sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db",
|
||||
"sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df",
|
||||
"sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3",
|
||||
"sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86",
|
||||
"sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2",
|
||||
"sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a",
|
||||
"sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf",
|
||||
"sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7",
|
||||
"sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394",
|
||||
"sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40",
|
||||
"sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3",
|
||||
"sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6",
|
||||
"sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74",
|
||||
"sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0",
|
||||
"sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3",
|
||||
"sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91",
|
||||
"sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5",
|
||||
"sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9",
|
||||
"sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8",
|
||||
"sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b",
|
||||
"sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6",
|
||||
"sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb",
|
||||
"sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73",
|
||||
"sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b",
|
||||
"sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df",
|
||||
"sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9",
|
||||
"sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f",
|
||||
"sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0",
|
||||
"sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857",
|
||||
"sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a",
|
||||
"sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249",
|
||||
"sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30",
|
||||
"sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292",
|
||||
"sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b",
|
||||
"sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d",
|
||||
"sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b",
|
||||
"sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c",
|
||||
"sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca",
|
||||
"sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7",
|
||||
"sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75",
|
||||
"sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae",
|
||||
"sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b",
|
||||
"sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470",
|
||||
"sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564",
|
||||
"sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9",
|
||||
"sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099",
|
||||
"sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0",
|
||||
"sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5",
|
||||
"sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19",
|
||||
"sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1",
|
||||
"sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"
|
||||
"sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67",
|
||||
"sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6",
|
||||
"sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257",
|
||||
"sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4",
|
||||
"sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676",
|
||||
"sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61",
|
||||
"sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc",
|
||||
"sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca",
|
||||
"sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7",
|
||||
"sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728",
|
||||
"sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305",
|
||||
"sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6",
|
||||
"sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379",
|
||||
"sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414",
|
||||
"sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04",
|
||||
"sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a",
|
||||
"sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf",
|
||||
"sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491",
|
||||
"sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559",
|
||||
"sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e",
|
||||
"sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274",
|
||||
"sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb",
|
||||
"sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b",
|
||||
"sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9",
|
||||
"sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b",
|
||||
"sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be",
|
||||
"sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506",
|
||||
"sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405",
|
||||
"sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113",
|
||||
"sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f",
|
||||
"sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5",
|
||||
"sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230",
|
||||
"sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d",
|
||||
"sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f",
|
||||
"sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a",
|
||||
"sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e",
|
||||
"sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61",
|
||||
"sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6",
|
||||
"sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d",
|
||||
"sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71",
|
||||
"sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22",
|
||||
"sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2",
|
||||
"sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3",
|
||||
"sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067",
|
||||
"sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc",
|
||||
"sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881",
|
||||
"sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3",
|
||||
"sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e",
|
||||
"sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac",
|
||||
"sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53",
|
||||
"sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0",
|
||||
"sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b",
|
||||
"sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83",
|
||||
"sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41",
|
||||
"sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c",
|
||||
"sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf",
|
||||
"sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
|
||||
"sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
|
||||
],
|
||||
"markers": "platform_python_implementation == 'CPython'",
|
||||
"version": "==2.0.2"
|
||||
"markers": "python_version >= '3.12' and platform_python_implementation == 'CPython'",
|
||||
"version": "==3.0.3"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
|
@ -729,11 +705,11 @@
|
|||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f",
|
||||
"sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"
|
||||
"sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e",
|
||||
"sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==67.8.0"
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==69.2.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
|
@ -769,46 +745,53 @@
|
|||
},
|
||||
"zope.event": {
|
||||
"hashes": [
|
||||
"sha256:73d9e3ef750cca14816a9c322c7250b0d7c9dbc337df5d1b807ff8d3d0b9e97c",
|
||||
"sha256:81d98813046fc86cc4136e3698fee628a3282f9c320db18658c21749235fce80"
|
||||
"sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26",
|
||||
"sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd"
|
||||
],
|
||||
"version": "==4.6"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.0"
|
||||
},
|
||||
"zope.interface": {
|
||||
"hashes": [
|
||||
"sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373",
|
||||
"sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb",
|
||||
"sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446",
|
||||
"sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8",
|
||||
"sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c",
|
||||
"sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8",
|
||||
"sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2",
|
||||
"sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f",
|
||||
"sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f",
|
||||
"sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5",
|
||||
"sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85",
|
||||
"sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc",
|
||||
"sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788",
|
||||
"sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518",
|
||||
"sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410",
|
||||
"sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464",
|
||||
"sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5",
|
||||
"sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d",
|
||||
"sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52",
|
||||
"sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca",
|
||||
"sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8",
|
||||
"sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2",
|
||||
"sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f",
|
||||
"sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58",
|
||||
"sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a",
|
||||
"sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d",
|
||||
"sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28",
|
||||
"sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990",
|
||||
"sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995",
|
||||
"sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30"
|
||||
"sha256:02adbab560683c4eca3789cc0ac487dcc5f5a81cc48695ec247f00803cafe2fe",
|
||||
"sha256:14e02a6fc1772b458ebb6be1c276528b362041217b9ca37e52ecea2cbdce9fac",
|
||||
"sha256:25e0af9663eeac6b61b231b43c52293c2cb7f0c232d914bdcbfd3e3bd5c182ad",
|
||||
"sha256:2606955a06c6852a6cff4abeca38346ed01e83f11e960caa9a821b3626a4467b",
|
||||
"sha256:396f5c94654301819a7f3a702c5830f0ea7468d7b154d124ceac823e2419d000",
|
||||
"sha256:3b240883fb43160574f8f738e6d09ddbdbf8fa3e8cea051603d9edfd947d9328",
|
||||
"sha256:3b6c62813c63c543a06394a636978b22dffa8c5410affc9331ce6cdb5bfa8565",
|
||||
"sha256:4ae9793f114cee5c464cc0b821ae4d36e1eba961542c6086f391a61aee167b6f",
|
||||
"sha256:4bce517b85f5debe07b186fc7102b332676760f2e0c92b7185dd49c138734b70",
|
||||
"sha256:4d45d2ba8195850e3e829f1f0016066a122bfa362cc9dc212527fc3d51369037",
|
||||
"sha256:4dd374927c00764fcd6fe1046bea243ebdf403fba97a937493ae4be2c8912c2b",
|
||||
"sha256:506f5410b36e5ba494136d9fa04c548eaf1a0d9c442b0b0e7a0944db7620e0ab",
|
||||
"sha256:59f7374769b326a217d0b2366f1c176a45a4ff21e8f7cebb3b4a3537077eff85",
|
||||
"sha256:5ee9789a20b0081dc469f65ff6c5007e67a940d5541419ca03ef20c6213dd099",
|
||||
"sha256:6fc711acc4a1c702ca931fdbf7bf7c86f2a27d564c85c4964772dadf0e3c52f5",
|
||||
"sha256:75d2ec3d9b401df759b87bc9e19d1b24db73083147089b43ae748aefa63067ef",
|
||||
"sha256:76e0531d86523be7a46e15d379b0e975a9db84316617c0efe4af8338dc45b80c",
|
||||
"sha256:8af82afc5998e1f307d5e72712526dba07403c73a9e287d906a8aa2b1f2e33dd",
|
||||
"sha256:8f5d2c39f3283e461de3655e03faf10e4742bb87387113f787a7724f32db1e48",
|
||||
"sha256:97785604824981ec8c81850dd25c8071d5ce04717a34296eeac771231fbdd5cd",
|
||||
"sha256:a3046e8ab29b590d723821d0785598e0b2e32b636a0272a38409be43e3ae0550",
|
||||
"sha256:abb0b3f2cb606981c7432f690db23506b1db5899620ad274e29dbbbdd740e797",
|
||||
"sha256:ac7c2046d907e3b4e2605a130d162b1b783c170292a11216479bb1deb7cadebe",
|
||||
"sha256:af27b3fe5b6bf9cd01b8e1c5ddea0a0d0a1b8c37dc1c7452f1e90bf817539c6d",
|
||||
"sha256:b386b8b9d2b6a5e1e4eadd4e62335571244cb9193b7328c2b6e38b64cfda4f0e",
|
||||
"sha256:b66335bbdbb4c004c25ae01cc4a54fd199afbc1fd164233813c6d3c2293bb7e1",
|
||||
"sha256:d54f66c511ea01b9ef1d1a57420a93fbb9d48a08ec239f7d9c581092033156d0",
|
||||
"sha256:de125151a53ecdb39df3cb3deb9951ed834dd6a110a9e795d985b10bb6db4532",
|
||||
"sha256:de7916380abaef4bb4891740879b1afcba2045aee51799dfd6d6ca9bdc71f35f",
|
||||
"sha256:e2fefad268ff5c5b314794e27e359e48aeb9c8bb2cbb5748a071757a56f6bb8f",
|
||||
"sha256:e7b2bed4eea047a949296e618552d3fed00632dc1b795ee430289bdd0e3717f3",
|
||||
"sha256:e87698e2fea5ca2f0a99dff0a64ce8110ea857b640de536c76d92aaa2a91ff3a",
|
||||
"sha256:ede888382882f07b9e4cd942255921ffd9f2901684198b88e247c7eabd27a000",
|
||||
"sha256:f444de0565db46d26c9fa931ca14f497900a295bd5eba480fc3fad25af8c763e",
|
||||
"sha256:fa994e8937e8ccc7e87395b7b35092818905cf27c651e3ff3e7f29729f5ce3ce",
|
||||
"sha256:febceb04ee7dd2aef08c2ff3d6f8a07de3052fc90137c507b0ede3ea80c21440"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==6.0"
|
||||
"version": "==6.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
@ -125,7 +124,3 @@ func transformLogcArgs(c *gin.Context, msg string, keysAndValues []interface{})
|
|||
}
|
||||
return msg, keysAndValues
|
||||
}
|
||||
|
||||
func init() {
|
||||
logrus.SetLevel(logrus.WarnLevel) // silence logs from zsais/go-gin-prometheus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,441 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
"helm.sh/chartmuseum/pkg/chartmuseum/logger"
|
||||
)
|
||||
|
||||
var defaultMetricPath = "/metrics"
|
||||
|
||||
// Standard default metrics
|
||||
//
|
||||
// counter, counter_vec, gauge, gauge_vec,
|
||||
// histogram, histogram_vec, summary, summary_vec
|
||||
var reqCnt = &Metric{
|
||||
ID: "reqCnt",
|
||||
Name: "requests_total",
|
||||
Description: "How many HTTP requests processed, partitioned by status code and HTTP method.",
|
||||
Type: "counter_vec",
|
||||
Args: []string{"code", "method", "handler", "host", "url"},
|
||||
}
|
||||
|
||||
var reqDur = &Metric{
|
||||
ID: "reqDur",
|
||||
Name: "request_duration_seconds",
|
||||
Description: "The HTTP request latencies in seconds.",
|
||||
Type: "histogram_vec",
|
||||
Args: []string{"code", "method", "url"},
|
||||
}
|
||||
|
||||
var resSz = &Metric{
|
||||
ID: "resSz",
|
||||
Name: "response_size_bytes",
|
||||
Description: "The HTTP response sizes in bytes.",
|
||||
Type: "summary",
|
||||
}
|
||||
|
||||
var reqSz = &Metric{
|
||||
ID: "reqSz",
|
||||
Name: "request_size_bytes",
|
||||
Description: "The HTTP request sizes in bytes.",
|
||||
Type: "summary",
|
||||
}
|
||||
|
||||
var standardMetrics = []*Metric{
|
||||
reqCnt,
|
||||
reqDur,
|
||||
resSz,
|
||||
reqSz,
|
||||
}
|
||||
|
||||
/*
|
||||
RequestCounterURLLabelMappingFn is a function which can be supplied to the middleware to control
|
||||
the cardinality of the request counter's "url" label, which might be required in some contexts.
|
||||
For instance, if for a "/customer/:name" route you don't want to generate a time series for every
|
||||
possible customer name, you could use this function:
|
||||
|
||||
func(c *gin.Context) string {
|
||||
url := c.Request.URL.Path
|
||||
for _, p := range c.Params {
|
||||
if p.Key == "name" {
|
||||
url = strings.Replace(url, p.Value, ":name", 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
which would map "/customer/alice" and "/customer/bob" to their template "/customer/:name".
|
||||
*/
|
||||
type RequestCounterURLLabelMappingFn func(c *gin.Context) string
|
||||
|
||||
// Metric is a definition for the name, description, type, ID, and
|
||||
// prometheus.Collector type (i.e. CounterVec, Summary, etc) of each metric
|
||||
type Metric struct {
|
||||
MetricCollector prometheus.Collector
|
||||
ID string
|
||||
Name string
|
||||
Description string
|
||||
Type string
|
||||
Args []string
|
||||
}
|
||||
|
||||
// Prometheus contains the metrics gathered by the instance and its path
|
||||
type Prometheus struct {
|
||||
reqCnt *prometheus.CounterVec
|
||||
reqDur *prometheus.HistogramVec
|
||||
reqSz, resSz prometheus.Summary
|
||||
router *gin.Engine
|
||||
listenAddress string
|
||||
logger *logger.Logger
|
||||
Ppg PrometheusPushGateway
|
||||
|
||||
MetricsList []*Metric
|
||||
MetricsPath string
|
||||
|
||||
ReqCntURLLabelMappingFn RequestCounterURLLabelMappingFn
|
||||
|
||||
// gin.Context string to use as a prometheus URL label
|
||||
URLLabelFromContext string
|
||||
IgnoreNotFoundMetric bool
|
||||
}
|
||||
|
||||
// PrometheusPushGateway contains the configuration for pushing to a Prometheus pushgateway (optional)
|
||||
type PrometheusPushGateway struct {
|
||||
// Push interval in seconds
|
||||
PushIntervalSeconds time.Duration
|
||||
|
||||
// Push Gateway URL in format http://domain:port
|
||||
// where JOBNAME can be any string of your choice
|
||||
PushGatewayURL string
|
||||
|
||||
// Local metrics URL where metrics are fetched from, this could be omitted in the future
|
||||
// if implemented using prometheus common/expfmt instead
|
||||
MetricsURL string
|
||||
|
||||
// pushgateway job name, defaults to "gin"
|
||||
Job string
|
||||
}
|
||||
|
||||
// newPrometheus generates a new set of metrics with a certain subsystem name
|
||||
func newPrometheus(subsystem string, customMetricsList ...[]*Metric) *Prometheus {
|
||||
var metricsList []*Metric
|
||||
|
||||
if len(customMetricsList) > 1 {
|
||||
panic("Too many args. NewPrometheus( string, <optional []*Metric> ).")
|
||||
} else if len(customMetricsList) == 1 {
|
||||
metricsList = customMetricsList[0]
|
||||
}
|
||||
|
||||
metricsList = append(metricsList, standardMetrics...)
|
||||
|
||||
p := &Prometheus{
|
||||
MetricsList: metricsList,
|
||||
MetricsPath: defaultMetricPath,
|
||||
ReqCntURLLabelMappingFn: func(c *gin.Context) string {
|
||||
return c.Request.URL.Path // i.e. by default do nothing, i.e. return URL as is
|
||||
},
|
||||
}
|
||||
|
||||
p.registerMetrics(subsystem)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func NewPrometheus(subsystem string, logger *logger.Logger, customMetricsList ...[]*Metric) *Prometheus {
|
||||
p := newPrometheus(subsystem, customMetricsList...)
|
||||
p.logger = logger
|
||||
return p
|
||||
}
|
||||
|
||||
// SetPushGateway sends metrics to a remote pushgateway exposed on pushGatewayURL
|
||||
// every pushIntervalSeconds. Metrics are fetched from metricsURL
|
||||
func (p *Prometheus) SetPushGateway(pushGatewayURL, metricsURL string, pushInterval time.Duration) {
|
||||
p.Ppg.PushGatewayURL = pushGatewayURL
|
||||
p.Ppg.MetricsURL = metricsURL
|
||||
p.Ppg.PushIntervalSeconds = pushInterval
|
||||
p.startPushTicker()
|
||||
}
|
||||
|
||||
// SetPushGatewayJob job name, defaults to "gin"
|
||||
func (p *Prometheus) SetPushGatewayJob(j string) {
|
||||
p.Ppg.Job = j
|
||||
}
|
||||
|
||||
// SetListenAddress for exposing metrics on address. If not set, it will be exposed at the
|
||||
// same address of the gin engine that is being used
|
||||
func (p *Prometheus) SetListenAddress(address string) {
|
||||
p.listenAddress = address
|
||||
if p.listenAddress != "" {
|
||||
p.router = gin.Default()
|
||||
}
|
||||
}
|
||||
|
||||
// SetListenAddressWithRouter for using a separate router to expose metrics. (this keeps things like GET /metrics out of
|
||||
// your content's access log).
|
||||
func (p *Prometheus) SetListenAddressWithRouter(listenAddress string, r *gin.Engine) {
|
||||
p.listenAddress = listenAddress
|
||||
if len(p.listenAddress) > 0 {
|
||||
p.router = r
|
||||
}
|
||||
}
|
||||
|
||||
// SetMetricsPath set metrics paths
|
||||
func (p *Prometheus) SetMetricsPath(e *gin.Engine) {
|
||||
if p.listenAddress != "" {
|
||||
p.router.GET(p.MetricsPath, prometheusHandler())
|
||||
p.runServer()
|
||||
} else {
|
||||
e.GET(p.MetricsPath, prometheusHandler())
|
||||
}
|
||||
}
|
||||
|
||||
// SetMetricsPathWithAuth set metrics paths with authentication
|
||||
func (p *Prometheus) SetMetricsPathWithAuth(e *gin.Engine, accounts gin.Accounts) {
|
||||
if p.listenAddress != "" {
|
||||
p.router.GET(p.MetricsPath, gin.BasicAuth(accounts), prometheusHandler())
|
||||
p.runServer()
|
||||
} else {
|
||||
e.GET(p.MetricsPath, gin.BasicAuth(accounts), prometheusHandler())
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prometheus) runServer() {
|
||||
if p.listenAddress != "" {
|
||||
go p.router.Run(p.listenAddress)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prometheus) getMetrics() []byte {
|
||||
response, err := http.Get(p.Ppg.MetricsURL)
|
||||
if err != nil && p.logger != nil {
|
||||
p.logger.Errorf("Error fetching metrics: %q", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
body, _ := io.ReadAll(response.Body)
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (p *Prometheus) getPushGatewayURL() string {
|
||||
h, _ := os.Hostname()
|
||||
if p.Ppg.Job == "" {
|
||||
p.Ppg.Job = "gin"
|
||||
}
|
||||
return p.Ppg.PushGatewayURL + "/metrics/job/" + p.Ppg.Job + "/instance/" + h
|
||||
}
|
||||
|
||||
func (p *Prometheus) sendMetricsToPushGateway(metrics []byte) {
|
||||
req, err := http.NewRequest("POST", p.getPushGatewayURL(), bytes.NewBuffer(metrics))
|
||||
if err != nil && p.logger != nil {
|
||||
p.logger.Errorf("Error creating request to push gateway: %q", err)
|
||||
}
|
||||
client := &http.Client{}
|
||||
if _, err = client.Do(req); err != nil {
|
||||
if p.logger != nil {
|
||||
p.logger.Errorf("Error sending to push gateway: %q", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prometheus) startPushTicker() {
|
||||
ticker := time.NewTicker(time.Second * p.Ppg.PushIntervalSeconds)
|
||||
go func() {
|
||||
for range ticker.C {
|
||||
p.sendMetricsToPushGateway(p.getMetrics())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// NewMetric associates prometheus.Collector based on Metric.Type
|
||||
func NewMetric(m *Metric, subsystem string) prometheus.Collector {
|
||||
var metric prometheus.Collector
|
||||
switch m.Type {
|
||||
case "counter_vec":
|
||||
metric = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
m.Args,
|
||||
)
|
||||
case "counter":
|
||||
metric = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
)
|
||||
case "gauge_vec":
|
||||
metric = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
m.Args,
|
||||
)
|
||||
case "gauge":
|
||||
metric = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
)
|
||||
case "histogram_vec":
|
||||
metric = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
m.Args,
|
||||
)
|
||||
case "histogram":
|
||||
metric = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
)
|
||||
case "summary_vec":
|
||||
metric = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
m.Args,
|
||||
)
|
||||
case "summary":
|
||||
metric = prometheus.NewSummary(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: subsystem,
|
||||
Name: m.Name,
|
||||
Help: m.Description,
|
||||
},
|
||||
)
|
||||
}
|
||||
return metric
|
||||
}
|
||||
|
||||
func (p *Prometheus) registerMetrics(subsystem string) {
|
||||
for _, metricDef := range p.MetricsList {
|
||||
metric := NewMetric(metricDef, subsystem)
|
||||
if err := prometheus.Register(metric); err != nil {
|
||||
if p.logger != nil {
|
||||
p.logger.Errorf("%s could not be registered in Prometheus: %q", metricDef.Name, err)
|
||||
}
|
||||
}
|
||||
switch metricDef {
|
||||
case reqCnt:
|
||||
p.reqCnt = metric.(*prometheus.CounterVec)
|
||||
case reqDur:
|
||||
p.reqDur = metric.(*prometheus.HistogramVec)
|
||||
case resSz:
|
||||
p.resSz = metric.(prometheus.Summary)
|
||||
case reqSz:
|
||||
p.reqSz = metric.(prometheus.Summary)
|
||||
}
|
||||
metricDef.MetricCollector = metric
|
||||
}
|
||||
}
|
||||
|
||||
// Use adds the middleware to a gin engine.
|
||||
func (p *Prometheus) Use(e *gin.Engine) {
|
||||
e.Use(p.HandlerFunc())
|
||||
p.SetMetricsPath(e)
|
||||
}
|
||||
|
||||
// UseWithAuth adds the middleware to a gin engine with BasicAuth.
|
||||
func (p *Prometheus) UseWithAuth(e *gin.Engine, accounts gin.Accounts) {
|
||||
e.Use(p.HandlerFunc())
|
||||
p.SetMetricsPathWithAuth(e, accounts)
|
||||
}
|
||||
|
||||
// HandlerFunc defines handler function for middleware
|
||||
func (p *Prometheus) HandlerFunc() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
if c.Request.URL.Path == p.MetricsPath {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
reqSz := computeApproximateRequestSize(c.Request)
|
||||
|
||||
c.Next()
|
||||
|
||||
if p.IgnoreNotFoundMetric {
|
||||
status := c.Writer.Status()
|
||||
// handle 404 and 405 error
|
||||
if status == http.StatusNotFound || status == http.StatusMethodNotAllowed {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
status := strconv.Itoa(c.Writer.Status())
|
||||
elapsed := float64(time.Since(start)) / float64(time.Second)
|
||||
resSz := float64(c.Writer.Size())
|
||||
|
||||
url := p.ReqCntURLLabelMappingFn(c)
|
||||
// jlambert Oct 2018 - sidecar specific mod
|
||||
if len(p.URLLabelFromContext) > 0 {
|
||||
u, found := c.Get(p.URLLabelFromContext)
|
||||
if !found {
|
||||
u = "unknown"
|
||||
}
|
||||
url = u.(string)
|
||||
}
|
||||
p.reqDur.WithLabelValues(status, c.Request.Method, url).Observe(elapsed)
|
||||
p.reqCnt.WithLabelValues(status, c.Request.Method, c.HandlerName(), c.Request.Host, url).Inc()
|
||||
p.reqSz.Observe(float64(reqSz))
|
||||
p.resSz.Observe(resSz)
|
||||
}
|
||||
}
|
||||
|
||||
func prometheusHandler() gin.HandlerFunc {
|
||||
h := promhttp.Handler()
|
||||
return func(c *gin.Context) {
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
}
|
||||
|
||||
// From https://github.com/DanielHeckrath/gin-prometheus/blob/master/gin_prometheus.go
|
||||
func computeApproximateRequestSize(r *http.Request) int {
|
||||
s := 0
|
||||
if r.URL != nil {
|
||||
s = len(r.URL.Path)
|
||||
}
|
||||
|
||||
s += len(r.Method)
|
||||
s += len(r.Proto)
|
||||
for name, values := range r.Header {
|
||||
s += len(name)
|
||||
for _, value := range values {
|
||||
s += len(value)
|
||||
}
|
||||
}
|
||||
s += len(r.Host)
|
||||
|
||||
// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
|
||||
|
||||
if r.ContentLength != -1 {
|
||||
s += int(r.ContentLength)
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -30,9 +30,10 @@ import (
|
|||
cm_auth "github.com/chartmuseum/auth"
|
||||
limits "github.com/gin-contrib/size"
|
||||
"github.com/gin-gonic/gin"
|
||||
ginprometheus "github.com/zsais/go-gin-prometheus"
|
||||
)
|
||||
|
||||
var _ http.Handler = (*Router)(nil)
|
||||
|
||||
type (
|
||||
// Router handles all incoming HTTP requests
|
||||
Router struct {
|
||||
|
@ -100,8 +101,9 @@ func NewRouter(options RouterOptions) *Router {
|
|||
engine.Use(limits.RequestSizeLimiter(int64(options.MaxUploadSize)))
|
||||
|
||||
if options.EnableMetrics {
|
||||
p := ginprometheus.NewPrometheus("chartmuseum")
|
||||
p := NewPrometheus("chartmuseum", options.Logger)
|
||||
p.ReqCntURLLabelMappingFn = mapURLWithParamsBackToRouteTemplate
|
||||
p.IgnoreNotFoundMetric = true
|
||||
p.Use(engine)
|
||||
}
|
||||
|
||||
|
@ -120,7 +122,6 @@ func NewRouter(options RouterOptions) *Router {
|
|||
WriteTimeout: time.Duration(options.WriteTimeout) * time.Second,
|
||||
Host: options.Host,
|
||||
}
|
||||
|
||||
var err error
|
||||
var authorizer *cm_auth.Authorizer
|
||||
|
||||
|
@ -177,7 +178,7 @@ func (router *Router) Start(port int) {
|
|||
|
||||
server := http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", router.Host, port),
|
||||
Handler: router,
|
||||
Handler: router.Engine,
|
||||
ReadTimeout: router.ReadTimeout,
|
||||
WriteTimeout: router.WriteTimeout,
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ type (
|
|||
// AlwaysRegenerateIndex represents if the museum always return the up-to-date chart
|
||||
// which means that the GetChart will increase its latency , be careful to enable this .
|
||||
AlwaysRegenerateIndex bool
|
||||
JSONIndex bool
|
||||
}
|
||||
|
||||
// Server is a generic interface for web servers
|
||||
|
@ -151,6 +152,7 @@ func NewServer(options ServerOptions) (Server, error) {
|
|||
// EnforceSemver2 - see https://github.com/helm/chartmuseum/issues/485 for more info
|
||||
EnforceSemver2: options.EnforceSemver2,
|
||||
AlwaysRegenerateIndex: options.AlwaysRegenerateIndex,
|
||||
JSONIndex: options.JSONIndex,
|
||||
})
|
||||
|
||||
return server, err
|
||||
|
|
|
@ -152,11 +152,12 @@ func (server *MultiTenantServer) regenerateRepositoryIndexWorker(log cm_logger.L
|
|||
"repo", repo,
|
||||
)
|
||||
index := &cm_repo.Index{
|
||||
IndexFile: entry.RepoIndex.IndexFile,
|
||||
RepoName: repo,
|
||||
Raw: entry.RepoIndex.Raw,
|
||||
ChartURL: entry.RepoIndex.ChartURL,
|
||||
IndexLock: sync.RWMutex{},
|
||||
IndexFile: entry.RepoIndex.IndexFile,
|
||||
RepoName: repo,
|
||||
Raw: entry.RepoIndex.Raw,
|
||||
ChartURL: entry.RepoIndex.ChartURL,
|
||||
IndexLock: sync.RWMutex{},
|
||||
OutputJSON: server.JSONIndex,
|
||||
}
|
||||
|
||||
for _, object := range diff.Removed {
|
||||
|
@ -442,23 +443,28 @@ func (server *MultiTenantServer) newRepositoryIndex(log cm_logger.LoggingFn, rep
|
|||
}
|
||||
|
||||
if !server.UseStatefiles {
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo)
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo, server.JSONIndex)
|
||||
}
|
||||
|
||||
objectPath := pathutil.Join(repo, cm_repo.StatefileFilename)
|
||||
object, err := server.StorageBackend.GetObject(objectPath)
|
||||
if err != nil {
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo)
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo, server.JSONIndex)
|
||||
}
|
||||
|
||||
indexFile := &cm_repo.IndexFile{}
|
||||
err = yaml.Unmarshal(object.Content, indexFile)
|
||||
if json.Valid(object.Content) {
|
||||
err = json.Unmarshal(object.Content, indexFile)
|
||||
} else {
|
||||
err = yaml.Unmarshal(object.Content, indexFile)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log(cm_logger.WarnLevel, "index-cache.yaml found but could not be parsed",
|
||||
"repo", repo,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo)
|
||||
return cm_repo.NewIndex(chartURL, repo, serverInfo, server.JSONIndex)
|
||||
}
|
||||
|
||||
log(cm_logger.DebugLevel, "index-cache.yaml loaded",
|
||||
|
@ -466,11 +472,12 @@ func (server *MultiTenantServer) newRepositoryIndex(log cm_logger.LoggingFn, rep
|
|||
)
|
||||
|
||||
return &cm_repo.Index{
|
||||
IndexFile: indexFile,
|
||||
RepoName: repo,
|
||||
Raw: object.Content,
|
||||
ChartURL: chartURL,
|
||||
IndexLock: sync.RWMutex{},
|
||||
IndexFile: indexFile,
|
||||
RepoName: repo,
|
||||
Raw: object.Content,
|
||||
ChartURL: chartURL,
|
||||
IndexLock: sync.RWMutex{},
|
||||
OutputJSON: server.JSONIndex,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -445,8 +445,7 @@ func (server *MultiTenantServer) postPackageAndProvenanceRequestHandler(c *gin.C
|
|||
"filename", ppf.filename,
|
||||
"field", ppf.field,
|
||||
)
|
||||
err := server.StorageBackend.PutObject(pathutil.Join(repo, ppf.filename), ppf.content)
|
||||
if err == nil {
|
||||
if err := server.PutWithLimit(&gin.Context{}, log, repo, ppf.filename, ppf.content); err == nil {
|
||||
storedFiles = append(storedFiles, ppf)
|
||||
} else {
|
||||
// Clean up what's already been saved
|
||||
|
|
|
@ -73,6 +73,7 @@ type (
|
|||
EnforceSemver2 bool
|
||||
WebTemplatePath string
|
||||
AlwaysRegenerateIndex bool
|
||||
JSONIndex bool
|
||||
}
|
||||
|
||||
ObjectsPerChartLimit struct {
|
||||
|
@ -106,6 +107,7 @@ type (
|
|||
// Deprecated: see https://github.com/helm/chartmuseum/issues/485 for more info
|
||||
EnforceSemver2 bool
|
||||
AlwaysRegenerateIndex bool
|
||||
JSONIndex bool
|
||||
}
|
||||
|
||||
tenantInternals struct {
|
||||
|
@ -166,6 +168,7 @@ func NewMultiTenantServer(options MultiTenantServerOptions) (*MultiTenantServer,
|
|||
WebTemplatePath: options.WebTemplatePath,
|
||||
ArtifactHubRepoID: options.ArtifactHubRepoID,
|
||||
AlwaysRegenerateIndex: options.AlwaysRegenerateIndex,
|
||||
JSONIndex: options.JSONIndex,
|
||||
}
|
||||
|
||||
if server.WebTemplatePath != "" {
|
||||
|
|
|
@ -951,6 +951,37 @@ func (suite *MultiTenantServerTestSuite) TestPerChartLimit() {
|
|||
suite.Equal(200, res.Status(), "200 GET /api/charts/mychart-service-0.0.1")
|
||||
}
|
||||
|
||||
func (suite *MultiTenantServerTestSuite) TestPerChartLimitWithFormData() {
|
||||
ns := "per-chart-limit"
|
||||
|
||||
expectUploadFiles := []string{
|
||||
testServiceTarballPathV0,
|
||||
testTarballPathV0,
|
||||
testTarballPathV2,
|
||||
testTarballPath,
|
||||
}
|
||||
|
||||
for _, f := range expectUploadFiles {
|
||||
buf, w := suite.getBodyWithMultipartFormFiles([]string{"chart"}, []string{f})
|
||||
res := suite.doRequest(ns, "POST", "/api/charts", buf, w.FormDataContentType())
|
||||
suite.Equal(201, res.Status(), "201 POST /api/charts")
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
res := suite.doRequest(ns, "GET", "/api/charts/mychart/0.2.0", nil, "")
|
||||
suite.Equal(200, res.Status(), "200 GET /api/charts/mychart-0.2.0")
|
||||
|
||||
res = suite.doRequest(ns, "GET", "/api/charts/mychart/0.1.0", nil, "")
|
||||
suite.Equal(200, res.Status(), "200 GET /api/charts/mychart-0.1.0")
|
||||
|
||||
res = suite.doRequest(ns, "GET", "/api/charts/mychart/0.0.1", nil, "")
|
||||
suite.Equal(404, res.Status(), "200 GET /api/charts/mychart-0.0.1")
|
||||
|
||||
res = suite.doRequest(ns, "GET", "/api/charts/mychart-service/0.0.1", nil, "")
|
||||
suite.Equal(200, res.Status(), "200 GET /api/charts/mychart-service-0.0.1")
|
||||
}
|
||||
|
||||
func (suite *MultiTenantServerTestSuite) TestMaxUploadSizeServer() {
|
||||
// trigger 413s, "request too large"
|
||||
content, err := os.ReadFile(testTarballPath)
|
||||
|
@ -971,13 +1002,16 @@ func (suite *MultiTenantServerTestSuite) TestMaxUploadSizeServer() {
|
|||
}
|
||||
|
||||
func (suite *MultiTenantServerTestSuite) TestMetrics() {
|
||||
res := suite.doRequest("depth1", "GET", "bad-url", nil, "")
|
||||
suite.Equal(404, res.Status(), "404 GET bad-url")
|
||||
|
||||
apiPrefix := pathutil.Join("/api", "a")
|
||||
|
||||
content, err := os.ReadFile(testTarballPath)
|
||||
suite.Nil(err, "error opening test tarball")
|
||||
|
||||
body := bytes.NewBuffer(content)
|
||||
res := suite.doRequest("depth1", "POST", fmt.Sprintf("%s/charts", apiPrefix), body, "")
|
||||
res = suite.doRequest("depth1", "POST", fmt.Sprintf("%s/charts", apiPrefix), body, "")
|
||||
suite.Equal(201, res.Status(), fmt.Sprintf("201 post %s/charts", apiPrefix))
|
||||
|
||||
otherChart, err := os.ReadFile(testTarballPathV2)
|
||||
|
@ -1011,7 +1045,8 @@ func (suite *MultiTenantServerTestSuite) TestMetrics() {
|
|||
if totalChartsServed && totalVersionsServed {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
notServeBadURL := !strings.Contains(metrics, "bad-url")
|
||||
return notServeBadURL
|
||||
}, 10*time.Second, time.Second)
|
||||
|
||||
// Ensure that we have the Gauges as documented
|
||||
|
|
|
@ -138,6 +138,15 @@ var configVars = map[string]configVar{
|
|||
EnvVar: "DISABLE_STATEFILES",
|
||||
},
|
||||
},
|
||||
"json-index": {
|
||||
Type: boolType,
|
||||
Default: false,
|
||||
CLIFlag: cli.BoolFlag{
|
||||
Name: "json-index",
|
||||
Usage: "generates an index in JSON format, improves parsing performance for large index files",
|
||||
EnvVar: "JSON_INDEX",
|
||||
},
|
||||
},
|
||||
"allowoverwrite": {
|
||||
Type: boolType,
|
||||
Default: false,
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package repo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -51,16 +52,17 @@ type (
|
|||
Raw []byte `json:"c"`
|
||||
ChartURL string `json:"d"`
|
||||
IndexLock sync.RWMutex
|
||||
OutputJSON bool
|
||||
}
|
||||
)
|
||||
|
||||
// NewIndex creates a new instance of Index
|
||||
func NewIndex(chartURL string, repo string, serverInfo *ServerInfo) *Index {
|
||||
func NewIndex(chartURL string, repo string, serverInfo *ServerInfo, outputJSON bool) *Index {
|
||||
indexFile := &IndexFile{
|
||||
IndexFile: &helm_repo.IndexFile{},
|
||||
ServerInfo: serverInfo,
|
||||
}
|
||||
index := Index{indexFile, repo, []byte{}, chartURL, sync.RWMutex{}}
|
||||
index := Index{indexFile, repo, []byte{}, chartURL, sync.RWMutex{}, outputJSON}
|
||||
index.Entries = map[string]helm_repo.ChartVersions{}
|
||||
index.APIVersion = helm_repo.APIVersionV1
|
||||
index.Regenerate()
|
||||
|
@ -68,10 +70,16 @@ func NewIndex(chartURL string, repo string, serverInfo *ServerInfo) *Index {
|
|||
}
|
||||
|
||||
// Regenerate sorts entries in index file and sets current time for generated key
|
||||
func (index *Index) Regenerate() error {
|
||||
func (index *Index) Regenerate() (err error) {
|
||||
index.SortEntries()
|
||||
index.Generated = time.Now().Round(time.Second)
|
||||
raw, err := yaml.Marshal(index.IndexFile)
|
||||
|
||||
var raw []byte
|
||||
if index.OutputJSON {
|
||||
raw, err = json.Marshal(index.IndexFile)
|
||||
} else {
|
||||
raw, err = yaml.Marshal(index.IndexFile)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package repo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -24,6 +25,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
helm_repo "helm.sh/helm/v3/pkg/repo"
|
||||
|
@ -51,7 +53,7 @@ func getChartVersion(name string, patch int, created time.Time) *helm_repo.Chart
|
|||
}
|
||||
|
||||
func (suite *IndexTestSuite) SetupSuite() {
|
||||
suite.Index = NewIndex("", "", &ServerInfo{})
|
||||
suite.Index = NewIndex("", "", &ServerInfo{}, false)
|
||||
now := time.Now()
|
||||
for _, name := range []string{"a", "b", "c"} {
|
||||
for i := 0; i < 10; i++ {
|
||||
|
@ -94,13 +96,13 @@ func (suite *IndexTestSuite) TestRemove() {
|
|||
}
|
||||
|
||||
func (suite *IndexTestSuite) TestChartURLs() {
|
||||
index := NewIndex("", "", &ServerInfo{})
|
||||
index := NewIndex("", "", &ServerInfo{}, false)
|
||||
chartVersion := getChartVersion("a", 0, time.Now())
|
||||
index.AddEntry(chartVersion)
|
||||
suite.Equal("charts/a-1.0.0.tgz",
|
||||
index.Entries["a"][0].URLs[0], "relative chart url")
|
||||
|
||||
index = NewIndex("http://mysite.com:8080", "", &ServerInfo{})
|
||||
index = NewIndex("http://mysite.com:8080", "", &ServerInfo{}, false)
|
||||
chartVersion = getChartVersion("a", 0, time.Now())
|
||||
index.AddEntry(chartVersion)
|
||||
suite.Equal("http://mysite.com:8080/charts/a-1.0.0.tgz",
|
||||
|
@ -109,16 +111,37 @@ func (suite *IndexTestSuite) TestChartURLs() {
|
|||
|
||||
func (suite *IndexTestSuite) TestServerInfo() {
|
||||
serverInfo := &ServerInfo{}
|
||||
index := NewIndex("", "", serverInfo)
|
||||
index := NewIndex("", "", serverInfo, false)
|
||||
suite.False(strings.Contains(string(index.Raw), "contextPath: /v1/helm"), "context path not in index")
|
||||
|
||||
serverInfo = &ServerInfo{
|
||||
ContextPath: "/v1/helm",
|
||||
}
|
||||
index = NewIndex("", "", serverInfo)
|
||||
index = NewIndex("", "", serverInfo, false)
|
||||
suite.True(strings.Contains(string(index.Raw), "contextPath: /v1/helm"), "context path is in index")
|
||||
}
|
||||
|
||||
func (suite *IndexTestSuite) TestYAMLIndex() {
|
||||
index := NewIndex("", "", &ServerInfo{}, false)
|
||||
chartVersion := getChartVersion("a", 0, time.Now())
|
||||
index.AddEntry(chartVersion)
|
||||
suite.NoError(index.Regenerate())
|
||||
|
||||
suite.False(json.Valid(index.Raw))
|
||||
suite.NoError(yaml.Unmarshal(index.Raw, &IndexFile{}))
|
||||
}
|
||||
|
||||
func (suite *IndexTestSuite) TestJSONIndex() {
|
||||
index := NewIndex("", "", &ServerInfo{}, true)
|
||||
chartVersion := getChartVersion("a", 0, time.Now())
|
||||
index.AddEntry(chartVersion)
|
||||
suite.NoError(index.Regenerate())
|
||||
|
||||
// Since YAML is a superset of JSON, any valid JSON should be valid YAML
|
||||
suite.True(json.Valid(index.Raw))
|
||||
suite.NoError(yaml.Unmarshal(index.Raw, &IndexFile{}))
|
||||
}
|
||||
|
||||
func TestIndexTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(IndexTestSuite))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue