1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] Authentication Service V1 (#1592)

This commit is contained in:
Adam Janikowski 2024-02-14 09:14:32 +01:00 committed by GitHub
parent 6b68e581e2
commit a3ee668251
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 2427 additions and 103 deletions

View file

@ -53,6 +53,10 @@ linters-settings:
alias: pbShutdownV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shutdown/v1
alias: pbImplShutdownV1
- pkg: github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition
alias: pbAuthenticationV1
- pkg: github.com/arangodb/kube-arangodb/integrations/authentication/v1
alias: pbImplAuthenticationV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shared/v1/definition
alias: pbSharedV1
- pkg: github.com/arangodb/kube-arangodb/integrations/shared/v1

View file

@ -223,16 +223,40 @@ endif
BINNAME := $(PROJECT)
BIN := $(BINDIR)/$(BINNAME)
VBIN_LINUX_AMD64 := $(BINDIR)/$(RELEASE_MODE)/linux/amd64/$(BINNAME)
VBIN_LINUX_ARM64 := $(BINDIR)/$(RELEASE_MODE)/linux/arm64/$(BINNAME)
BIN_OPS_NAME := $(PROJECT)_ops
BIN_OPS := $(BINDIR)/$(BIN_OPS_NAME)
VBIN_OPS_LINUX_AMD64 := $(BINDIR)/$(RELEASE_MODE)/linux/amd64/$(BIN_OPS_NAME)
VBIN_OPS_LINUX_ARM64 := $(BINDIR)/$(RELEASE_MODE)/linux/arm64/$(BIN_OPS_NAME)
VBIN_OPS_DARWIN_AMD64 := $(BINDIR)/$(RELEASE_MODE)/darwin/amd64/$(BIN_OPS_NAME)
VBIN_OPS_DARWIN_ARM64 := $(BINDIR)/$(RELEASE_MODE)/darwin/arm64/$(BIN_OPS_NAME)
BIN_INT_NAME := $(PROJECT)_integration
BIN_INT := $(BINDIR)/$(BIN_INT_NAME)
define binary
$(eval _OS:=$(call UPPER_ENV,$1))
$(eval _ARCH:=$(call UPPER_ENV,$2))
VBIN_$(_OS)_$(_ARCH) := $(BINDIR)/$(RELEASE_MODE)/$1/$2/$(BINNAME)
VBIN_OPS_$(_OS)_$(_ARCH) := $(BINDIR)/$(RELEASE_MODE)/$1/$2/$(BIN_OPS_NAME)
VBIN_INT_$(_OS)_$(_ARCH) := $(BINDIR)/$(RELEASE_MODE)/$1/$2/$(BIN_INT_NAME)
$$(VBIN_$(_OS)_$(_ARCH)): $$(SOURCES) dashboard/assets.go VERSION
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/$1/$2
CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build $${GOBUILDARGS} --tags "$$(GOBUILDTAGS)" $$(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$$(GOBUILDGCFLAGS)" -ldflags "$$(GOBUILDLDFLAGS)" -o $$@ ./cmd/main
$$(VBIN_OPS_$(_OS)_$(_ARCH)): $$(SOURCES) dashboard/assets.go VERSION
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/$1/$2
CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build $${GOBUILDARGS} --tags "$$(GOBUILDTAGS)" $$(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$$(GOBUILDGCFLAGS)" -ldflags "$$(GOBUILDLDFLAGS)" -o $$@ ./cmd/main-ops
$$(VBIN_INT_$(_OS)_$(_ARCH)): $$(SOURCES) dashboard/assets.go VERSION
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/$1/$2
CGO_ENABLED=0 GOOS=$1 GOARCH=$2 go build $${GOBUILDARGS} --tags "$$(GOBUILDTAGS)" $$(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$$(GOBUILDGCFLAGS)" -ldflags "$$(GOBUILDLDFLAGS)" -o $$@ ./cmd/main-int
bin-all: $$(VBIN_$(_OS)_$(_ARCH)) $$(VBIN_OPS_$(_OS)_$(_ARCH)) $$(VBIN_INT_$(_OS)_$(_ARCH))
endef
$(eval $(call binary,linux,amd64))
$(eval $(call binary,linux,arm64))
$(eval $(call binary,darwin,amd64))
$(eval $(call binary,darwin,arm64))
ifdef VERBOSE
TESTVERBOSEOPTIONS := -v
@ -421,27 +445,12 @@ dashboard/assets.go:
$(DASHBOARDBUILDIMAGE)
$(GOASSETSBUILDER) -s /dashboard/build/ -o dashboard/assets.go -p dashboard dashboard/build
.PHONY: bin bin-all
# Binaries
.PHONY: bin
bin: $(BIN)
bin-all: $(BIN) $(VBIN_LINUX_AMD64) $(VBIN_LINUX_ARM64)
$(VBIN_LINUX_AMD64): $(SOURCES) dashboard/assets.go VERSION
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/linux/amd64
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_LINUX_AMD64) ./cmd/main
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_OPS_LINUX_AMD64) ./cmd/main-ops
$(VBIN_LINUX_ARM64): $(SOURCES) dashboard/assets.go VERSION
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/linux/arm64
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_LINUX_ARM64) ./cmd/main
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_OPS_LINUX_ARM64) ./cmd/main-ops
bin-ops-all: $(VBIN_LINUX_AMD64) $(VBIN_LINUX_ARM64)
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/darwin/amd64
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_OPS_DARWIN_AMD64) ./cmd/main-ops
@mkdir -p $(BINDIR)/$(RELEASE_MODE)/darwin/arm64
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build ${GOBUILDARGS} --tags "$(GOBUILDTAGS)" $(COMPILE_DEBUG_FLAGS) -installsuffix netgo -gcflags=all="$(GOBUILDGCFLAGS)" -ldflags "$(GOBUILDLDFLAGS)" -o $(VBIN_OPS_DARWIN_ARM64) ./cmd/main-ops
$(BIN): $(VBIN_LINUX_AMD64)
$(BIN): $(VBIN_LINUX_AMD64) $(VBIN_OPS_LINUX_AMD64) $(VBIN_INT_LINUX_AMD64)
@cp "$(VBIN_LINUX_AMD64)" "$(BIN)"
@cp "$(VBIN_OPS_LINUX_AMD64)" "$(BIN_OPS)"
@ -817,7 +826,7 @@ check-community:
@$(MAKE) _check RELEASE_MODE=community
_check: sync-crds
@$(MAKE) fmt yamlfmt license-verify linter run-unit-tests bin vulncheck-optional
@$(MAKE) fmt yamlfmt license-verify linter run-unit-tests bin-all vulncheck-optional
generate: generate-internal generate-proto fmt yamlfmt

View file

@ -184,6 +184,7 @@ func init() {
var deprecatedStr string
f := cmdMain.Flags()
f.StringVar(&serverOptions.host, "server.host", defaultServerHost, "Host to listen on")
f.IntVar(&serverOptions.port, "server.port", defaultServerPort, "Port to listen on")
f.StringVar(&serverOptions.tlsSecretName, "server.tls-secret-name", "", "Name of secret containing tls.crt & tls.key for HTTPS server (if empty, self-signed certificate is used)")

View file

@ -20,10 +20,20 @@
package cmd
import "github.com/arangodb/kube-arangodb/cmd/integrations"
import (
"github.com/spf13/cobra"
"github.com/arangodb/kube-arangodb/pkg/integrations"
)
func init() {
if err := integrations.Register(&cmdMain); err != nil {
subCommand := &cobra.Command{
Use: "integration",
}
if err := integrations.Register(subCommand); err != nil {
panic(err.Error())
}
cmdMain.AddCommand(subCommand)
}

60
cmd/main-int/main_int.go Normal file
View file

@ -0,0 +1,60 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package main
import (
goflag "flag"
"os"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"github.com/arangodb/kube-arangodb/pkg/integrations"
)
var (
cmd = cobra.Command{
Use: "arangodb_int",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Usage()
},
}
)
func init() {
if err := integrations.Register(&cmd); err != nil {
panic(err.Error())
}
}
func Execute() int {
flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
if err := cmd.Execute(); err != nil {
return 1
}
return 0
}
func main() {
os.Exit(Execute())
}

26
go.mod
View file

@ -36,11 +36,11 @@ require (
github.com/fsnotify/fsnotify v1.7.0
github.com/gin-gonic/gin v1.9.1
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.3.1
github.com/google/uuid v1.4.0
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15
github.com/josephburnett/jd v1.6.1
github.com/julienschmidt/httprouter v1.3.0
github.com/magiconair/properties v1.8.5
github.com/magiconair/properties v1.8.7
github.com/pkg/errors v0.9.1
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.44.1
github.com/prometheus-operator/prometheus-operator/pkg/client v0.0.0-00010101000000-000000000000
@ -49,13 +49,13 @@ require (
github.com/prometheus/prom2json v1.3.3
github.com/robfig/cron v1.2.0
github.com/rs/zerolog v1.19.0
github.com/spf13/cobra v1.7.0
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
golang.org/x/sync v0.4.0
golang.org/x/sync v0.6.0
golang.org/x/sys v0.16.0
golang.org/x/text v0.14.0
golang.org/x/time v0.3.0
golang.org/x/time v0.5.0
google.golang.org/grpc v1.60.1
google.golang.org/protobuf v1.32.0
gopkg.in/yaml.v3 v3.0.1
@ -74,7 +74,7 @@ require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dchest/siphash v1.2.2 // indirect
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
@ -109,19 +109,19 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/stretchr/objx v0.4.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/tools v0.12.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect

71
go.sum
View file

@ -603,8 +603,6 @@ github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
@ -703,12 +701,14 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.2 h1:9DFz8tQwl9pTVt5iok/9zKyzA1Q6bRGiF3HPiEEVr9I=
github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9 h1:74lLNRzvsdIlkTgfDSMuaPjBr4cf6k7pwQQANm/yLKU=
@ -749,7 +749,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
@ -784,17 +783,11 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
@ -867,7 +860,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -916,8 +908,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
@ -937,7 +929,6 @@ github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@ -1029,11 +1020,8 @@ github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuz
github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -1073,7 +1061,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
@ -1114,8 +1101,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible h1:Jd6xfriVlJ6hWPvYOE0Ni0QWcNTLRehfGPFxr3eSL80=
github.com/pavel-v-chernykh/keystore-go v2.1.0+incompatible/go.mod h1:xlUlxe/2ItGlQyMTstqeDv9r3U4obH7xYd26TbDQutY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
@ -1128,8 +1115,9 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.46.0 h1:J+aQlaDVIemgZDR1f/48MBaiA7rDTm6OyKSRhDX2ZTY=
@ -1215,8 +1203,9 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@ -1318,8 +1307,8 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1399,7 +1388,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -1455,8 +1443,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1487,8 +1475,8 @@ golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1506,8 +1494,8 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1625,8 +1613,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1652,8 +1640,9 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -1728,8 +1717,8 @@ golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1844,7 +1833,6 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@ -2023,7 +2011,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
@ -2047,7 +2034,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@ -2070,16 +2056,13 @@ k8s.io/client-go v0.28.5 h1:6UNmc33vuJhh3+SAOEKku3QnKa+DtPKGnhO2MR0IEbk=
k8s.io/client-go v0.28.5/go.mod h1:+pt086yx1i0HAlHzM9S+RZQDqdlzuXFl4hY01uhpcpA=
k8s.io/component-base v0.28.5/go.mod h1:gw2d8O28okS9RrsPuJnD2mFl2It0HH9neHiGi2xoXcY=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kms v0.28.5/go.mod h1:BuOJ8gZRpTFPw4g/OXNfy9ljhuG+U2mT8SK3+3TuCxs=
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=

View file

@ -0,0 +1,144 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"io"
"os"
"path"
"sort"
"time"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
const MaxSize = 128
type cache struct {
parent *implementation
eol time.Time
signingToken []byte
validationTokens [][]byte
}
func (i *implementation) newCache() (*cache, error) {
files, err := os.ReadDir(i.cfg.Path)
if err != nil {
return nil, err
}
var keys []string
var tokens = make(map[string][]byte)
for _, file := range files {
if file.IsDir() {
continue
}
data, err := util.OpenWithRead(path.Join(i.cfg.Path, file.Name()), MaxSize)
if err != nil {
continue
}
if len(data) == 0 {
continue
}
buff := make([]byte, 32)
for id := range buff {
buff[id] = 0
}
copy(buff, data)
keys = append(keys, file.Name())
tokens[file.Name()] = buff
}
if len(keys) == 0 {
return nil, io.ErrUnexpectedEOF
}
sort.Strings(keys)
data := make([][]byte, len(keys))
for id := range data {
data[id] = tokens[keys[id]]
}
cache := cache{
parent: i,
eol: time.Now().Add(i.cfg.TTL),
signingToken: tokens[keys[0]],
validationTokens: data,
}
return &cache, nil
}
func (i *implementation) localGetCache() *cache {
if c := i.cache; c != nil && c.eol.After(time.Now()) {
return c
}
return nil
}
func (i *implementation) withCache() (*cache, error) {
if c := i.getCache(); c != nil {
return c, nil
}
return i.refreshCache()
}
func (i *implementation) getCache() *cache {
i.lock.RLock()
defer i.lock.RUnlock()
return i.localGetCache()
}
func (i *implementation) refreshCache() (*cache, error) {
i.lock.Lock()
defer i.lock.Unlock()
if c := i.localGetCache(); c != nil {
return c, nil
}
// Get was not successful, retry
if c, err := i.newCache(); err != nil {
return nil, err
} else if c == nil {
return nil, errors.Errorf("cache returned is nil")
} else {
i.cache = c
return i.cache, nil
}
}

View file

@ -0,0 +1,129 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"time"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/strings"
)
const (
DefaultAdminUser = "root"
DefaultUser = "root"
DefaultTTL = 15 * time.Second
DefaultTokenMinTTL = time.Minute
DefaultTokenMaxTTL = time.Hour
DefaultTokenDefaultTTL = time.Hour
)
type Mod func(c Configuration) Configuration
func NewConfiguration() Configuration {
return Configuration{
Enabled: true,
TTL: DefaultTTL,
Path: "",
Create: Token{
DefaultUser: DefaultUser,
AllowedUsers: nil,
MinTTL: DefaultTokenMinTTL,
MaxTTL: DefaultTokenMaxTTL,
DefaultTTL: DefaultTokenDefaultTTL,
},
}
}
type Configuration struct {
Enabled bool
TTL time.Duration
Path string
Create Token
}
func (c Configuration) With(mods ...Mod) Configuration {
n := c
for _, mod := range mods {
n = mod(n)
}
return n
}
func (c Configuration) Validate() error {
if c.Path == "" {
return errors.Errorf("Path should not be empty")
}
if c.TTL < 0 {
return errors.Errorf("TTLS should be not negative")
}
if err := c.Create.Validate(); err != nil {
return errors.Wrapf(err, "Token validation failed")
}
return nil
}
type Token struct {
DefaultUser string
AllowedUsers []string
MinTTL, MaxTTL, DefaultTTL time.Duration
}
func (t Token) Validate() error {
if t.MinTTL < 0 {
return errors.Errorf("MinTTL Cannot be lower than 0")
}
if t.MaxTTL < t.MinTTL {
return errors.Errorf("MaxTTL Cannot be lower than MinTTL")
}
if t.DefaultTTL < t.MinTTL {
return errors.Errorf("DefautTTL Cannot be lower than MinTTL")
}
if t.DefaultTTL > t.MaxTTL {
return errors.Errorf("DefautTTL Cannot be higher than MaxTTL")
}
if len(t.AllowedUsers) > 0 {
// We are enforcing allowed users
if !strings.ListContains(t.AllowedUsers, t.DefaultUser) {
return errors.Errorf("DefaultUser should be always allowed")
}
}
return nil
}

View file

@ -0,0 +1,531 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.1
// source: integrations/authentication/v1/definition/definition.proto
package definition
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// ValidateRequest defines request for AuthenticationV1 Validate Request
type ValidateRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Token specifies a token extracted from the request or used currently
Token string `protobuf:"bytes,1,opt,name=Token,proto3" json:"Token,omitempty"`
}
func (x *ValidateRequest) Reset() {
*x = ValidateRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ValidateRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateRequest) ProtoMessage() {}
func (x *ValidateRequest) ProtoReflect() protoreflect.Message {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateRequest.ProtoReflect.Descriptor instead.
func (*ValidateRequest) Descriptor() ([]byte, []int) {
return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{0}
}
func (x *ValidateRequest) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
// ValidateResponse defines response for AuthenticationV1 Validate Request
type ValidateResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// IsValid returns information about the validity of the token
IsValid bool `protobuf:"varint,1,opt,name=IsValid,proto3" json:"IsValid,omitempty"`
// Message message for the validation phase
Message string `protobuf:"bytes,2,opt,name=Message,proto3" json:"Message,omitempty"`
// Details returns token details if the token is valid
Details *ValidateResponseDetails `protobuf:"bytes,3,opt,name=Details,proto3,oneof" json:"Details,omitempty"`
}
func (x *ValidateResponse) Reset() {
*x = ValidateResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ValidateResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateResponse) ProtoMessage() {}
func (x *ValidateResponse) ProtoReflect() protoreflect.Message {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateResponse.ProtoReflect.Descriptor instead.
func (*ValidateResponse) Descriptor() ([]byte, []int) {
return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{1}
}
func (x *ValidateResponse) GetIsValid() bool {
if x != nil {
return x.IsValid
}
return false
}
func (x *ValidateResponse) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
func (x *ValidateResponse) GetDetails() *ValidateResponseDetails {
if x != nil {
return x.Details
}
return nil
}
// ValidateResponseDetails defines optional response for AuthenticationV1 Validate Request.
// Returned only if the Token provided in the request is valid.
type ValidateResponseDetails struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Lifetime specify the lifetime of the token
Lifetime *durationpb.Duration `protobuf:"bytes,1,opt,name=Lifetime,proto3" json:"Lifetime,omitempty"`
// User returns the User used in the Token. If a user is not specified, `root` is returned
User string `protobuf:"bytes,2,opt,name=User,proto3" json:"User,omitempty"`
}
func (x *ValidateResponseDetails) Reset() {
*x = ValidateResponseDetails{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ValidateResponseDetails) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidateResponseDetails) ProtoMessage() {}
func (x *ValidateResponseDetails) ProtoReflect() protoreflect.Message {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidateResponseDetails.ProtoReflect.Descriptor instead.
func (*ValidateResponseDetails) Descriptor() ([]byte, []int) {
return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{2}
}
func (x *ValidateResponseDetails) GetLifetime() *durationpb.Duration {
if x != nil {
return x.Lifetime
}
return nil
}
func (x *ValidateResponseDetails) GetUser() string {
if x != nil {
return x.User
}
return ""
}
// CreateTokenRequest defines request for AuthenticationV1 CreateToken Request
type CreateTokenRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Lifetime specifies the lifetime of the token as duration. Defaults to 1 hour
Lifetime *durationpb.Duration `protobuf:"bytes,1,opt,name=Lifetime,proto3,oneof" json:"Lifetime,omitempty"`
// User specify the User for which token should be created. By default, the default user is used (root in most cases)
User *string `protobuf:"bytes,2,opt,name=User,proto3,oneof" json:"User,omitempty"`
}
func (x *CreateTokenRequest) Reset() {
*x = CreateTokenRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateTokenRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateTokenRequest) ProtoMessage() {}
func (x *CreateTokenRequest) ProtoReflect() protoreflect.Message {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateTokenRequest.ProtoReflect.Descriptor instead.
func (*CreateTokenRequest) Descriptor() ([]byte, []int) {
return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{3}
}
func (x *CreateTokenRequest) GetLifetime() *durationpb.Duration {
if x != nil {
return x.Lifetime
}
return nil
}
func (x *CreateTokenRequest) GetUser() string {
if x != nil && x.User != nil {
return *x.User
}
return ""
}
// CreateTokenResponse defines response for AuthenticationV1 CreateToken Request
type CreateTokenResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Lifetime specify the lifetime of the token as the duration
Lifetime *durationpb.Duration `protobuf:"bytes,1,opt,name=Lifetime,proto3" json:"Lifetime,omitempty"`
// User returns the User used in the Token
User string `protobuf:"bytes,2,opt,name=User,proto3" json:"User,omitempty"`
// Token returns the Token as a string
Token string `protobuf:"bytes,3,opt,name=Token,proto3" json:"Token,omitempty"`
}
func (x *CreateTokenResponse) Reset() {
*x = CreateTokenResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateTokenResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateTokenResponse) ProtoMessage() {}
func (x *CreateTokenResponse) ProtoReflect() protoreflect.Message {
mi := &file_integrations_authentication_v1_definition_definition_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateTokenResponse.ProtoReflect.Descriptor instead.
func (*CreateTokenResponse) Descriptor() ([]byte, []int) {
return file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP(), []int{4}
}
func (x *CreateTokenResponse) GetLifetime() *durationpb.Duration {
if x != nil {
return x.Lifetime
}
return nil
}
func (x *CreateTokenResponse) GetUser() string {
if x != nil {
return x.User
}
return ""
}
func (x *CreateTokenResponse) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
var File_integrations_authentication_v1_definition_definition_proto protoreflect.FileDescriptor
var file_integrations_authentication_v1_definition_definition_proto_rawDesc = []byte{
0x0a, 0x3a, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61,
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31,
0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x66, 0x69,
0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x61, 0x75,
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75,
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x27, 0x0a, 0x0f,
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x14, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9a, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x49, 0x73,
0x56, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, 0x73, 0x56,
0x61, 0x6c, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x46,
0x0a, 0x07, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x27, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x48, 0x00, 0x52, 0x07, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x44, 0x65, 0x74, 0x61, 0x69,
0x6c, 0x73, 0x22, 0x64, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x35, 0x0a,
0x08, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x4c, 0x69, 0x66, 0x65,
0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x22, 0x7f, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a,
0x0a, 0x08, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x08, 0x4c,
0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x55, 0x73,
0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72,
0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65,
0x42, 0x07, 0x0a, 0x05, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x22, 0x76, 0x0a, 0x13, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x35, 0x0a, 0x08, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x4c,
0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x54,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x32, 0xbd, 0x01, 0x0a, 0x10, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x4f, 0x0a, 0x08, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74,
0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f,
0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61, 0x75, 0x74,
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72,
0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_integrations_authentication_v1_definition_definition_proto_rawDescOnce sync.Once
file_integrations_authentication_v1_definition_definition_proto_rawDescData = file_integrations_authentication_v1_definition_definition_proto_rawDesc
)
func file_integrations_authentication_v1_definition_definition_proto_rawDescGZIP() []byte {
file_integrations_authentication_v1_definition_definition_proto_rawDescOnce.Do(func() {
file_integrations_authentication_v1_definition_definition_proto_rawDescData = protoimpl.X.CompressGZIP(file_integrations_authentication_v1_definition_definition_proto_rawDescData)
})
return file_integrations_authentication_v1_definition_definition_proto_rawDescData
}
var file_integrations_authentication_v1_definition_definition_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_integrations_authentication_v1_definition_definition_proto_goTypes = []interface{}{
(*ValidateRequest)(nil), // 0: authentication.ValidateRequest
(*ValidateResponse)(nil), // 1: authentication.ValidateResponse
(*ValidateResponseDetails)(nil), // 2: authentication.ValidateResponseDetails
(*CreateTokenRequest)(nil), // 3: authentication.CreateTokenRequest
(*CreateTokenResponse)(nil), // 4: authentication.CreateTokenResponse
(*durationpb.Duration)(nil), // 5: google.protobuf.Duration
}
var file_integrations_authentication_v1_definition_definition_proto_depIdxs = []int32{
2, // 0: authentication.ValidateResponse.Details:type_name -> authentication.ValidateResponseDetails
5, // 1: authentication.ValidateResponseDetails.Lifetime:type_name -> google.protobuf.Duration
5, // 2: authentication.CreateTokenRequest.Lifetime:type_name -> google.protobuf.Duration
5, // 3: authentication.CreateTokenResponse.Lifetime:type_name -> google.protobuf.Duration
0, // 4: authentication.AuthenticationV1.Validate:input_type -> authentication.ValidateRequest
3, // 5: authentication.AuthenticationV1.CreateToken:input_type -> authentication.CreateTokenRequest
1, // 6: authentication.AuthenticationV1.Validate:output_type -> authentication.ValidateResponse
4, // 7: authentication.AuthenticationV1.CreateToken:output_type -> authentication.CreateTokenResponse
6, // [6:8] is the sub-list for method output_type
4, // [4:6] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_integrations_authentication_v1_definition_definition_proto_init() }
func file_integrations_authentication_v1_definition_definition_proto_init() {
if File_integrations_authentication_v1_definition_definition_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_integrations_authentication_v1_definition_definition_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ValidateRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ValidateResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ValidateResponseDetails); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateTokenRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateTokenResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[1].OneofWrappers = []interface{}{}
file_integrations_authentication_v1_definition_definition_proto_msgTypes[3].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_integrations_authentication_v1_definition_definition_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_integrations_authentication_v1_definition_definition_proto_goTypes,
DependencyIndexes: file_integrations_authentication_v1_definition_definition_proto_depIdxs,
MessageInfos: file_integrations_authentication_v1_definition_definition_proto_msgTypes,
}.Build()
File_integrations_authentication_v1_definition_definition_proto = out.File
file_integrations_authentication_v1_definition_definition_proto_rawDesc = nil
file_integrations_authentication_v1_definition_definition_proto_goTypes = nil
file_integrations_authentication_v1_definition_definition_proto_depIdxs = nil
}

View file

@ -0,0 +1,85 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
syntax = "proto3";
import "google/protobuf/duration.proto";
option go_package = "github.com/arangodb/kube-arangodb/integrations/v1/definition";
package authentication;
// AuthenticationV1 define ServiceInterface for Authentication V1
service AuthenticationV1 {
// Validate and ensure that Authentication details are valid returns information about the user
rpc Validate (ValidateRequest) returns (ValidateResponse) {}
// CreateToken creates a token for the specified user
rpc CreateToken (CreateTokenRequest) returns (CreateTokenResponse) {}
}
// ValidateRequest defines request for AuthenticationV1 Validate Request
message ValidateRequest {
// Token specifies a token extracted from the request or used currently
string Token = 1;
}
// ValidateResponse defines response for AuthenticationV1 Validate Request
message ValidateResponse {
// IsValid returns information about the validity of the token
bool IsValid = 1;
// Message message for the validation phase
string Message = 2;
// Details returns token details if the token is valid
optional ValidateResponseDetails Details = 3;
}
// ValidateResponseDetails defines optional response for AuthenticationV1 Validate Request.
// Returned only if the Token provided in the request is valid.
message ValidateResponseDetails {
// Lifetime specify the lifetime of the token
google.protobuf.Duration Lifetime = 1;
// User returns the User used in the Token. If a user is not specified, `root` is returned
string User = 2;
}
// CreateTokenRequest defines request for AuthenticationV1 CreateToken Request
message CreateTokenRequest {
// Lifetime specifies the lifetime of the token as duration. Defaults to 1 hour
optional google.protobuf.Duration Lifetime = 1;
// User specify the User for which token should be created. By default, the default user is used (root in most cases)
optional string User = 2;
}
// CreateTokenResponse defines response for AuthenticationV1 CreateToken Request
message CreateTokenResponse {
// Lifetime specify the lifetime of the token as the duration
google.protobuf.Duration Lifetime = 1;
// User returns the User used in the Token
string User = 2;
// Token returns the Token as a string
string Token = 3;
}

View file

@ -0,0 +1,145 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.21.1
// source: integrations/authentication/v1/definition/definition.proto
package definition
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// AuthenticationV1Client is the client API for AuthenticationV1 service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type AuthenticationV1Client interface {
// Validate and ensure that Authentication details are valid returns information about the user
Validate(ctx context.Context, in *ValidateRequest, opts ...grpc.CallOption) (*ValidateResponse, error)
// CreateToken creates a token for the specified user
CreateToken(ctx context.Context, in *CreateTokenRequest, opts ...grpc.CallOption) (*CreateTokenResponse, error)
}
type authenticationV1Client struct {
cc grpc.ClientConnInterface
}
func NewAuthenticationV1Client(cc grpc.ClientConnInterface) AuthenticationV1Client {
return &authenticationV1Client{cc}
}
func (c *authenticationV1Client) Validate(ctx context.Context, in *ValidateRequest, opts ...grpc.CallOption) (*ValidateResponse, error) {
out := new(ValidateResponse)
err := c.cc.Invoke(ctx, "/authentication.AuthenticationV1/Validate", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authenticationV1Client) CreateToken(ctx context.Context, in *CreateTokenRequest, opts ...grpc.CallOption) (*CreateTokenResponse, error) {
out := new(CreateTokenResponse)
err := c.cc.Invoke(ctx, "/authentication.AuthenticationV1/CreateToken", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthenticationV1Server is the server API for AuthenticationV1 service.
// All implementations must embed UnimplementedAuthenticationV1Server
// for forward compatibility
type AuthenticationV1Server interface {
// Validate and ensure that Authentication details are valid returns information about the user
Validate(context.Context, *ValidateRequest) (*ValidateResponse, error)
// CreateToken creates a token for the specified user
CreateToken(context.Context, *CreateTokenRequest) (*CreateTokenResponse, error)
mustEmbedUnimplementedAuthenticationV1Server()
}
// UnimplementedAuthenticationV1Server must be embedded to have forward compatible implementations.
type UnimplementedAuthenticationV1Server struct {
}
func (UnimplementedAuthenticationV1Server) Validate(context.Context, *ValidateRequest) (*ValidateResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Validate not implemented")
}
func (UnimplementedAuthenticationV1Server) CreateToken(context.Context, *CreateTokenRequest) (*CreateTokenResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateToken not implemented")
}
func (UnimplementedAuthenticationV1Server) mustEmbedUnimplementedAuthenticationV1Server() {}
// UnsafeAuthenticationV1Server may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AuthenticationV1Server will
// result in compilation errors.
type UnsafeAuthenticationV1Server interface {
mustEmbedUnimplementedAuthenticationV1Server()
}
func RegisterAuthenticationV1Server(s grpc.ServiceRegistrar, srv AuthenticationV1Server) {
s.RegisterService(&AuthenticationV1_ServiceDesc, srv)
}
func _AuthenticationV1_Validate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ValidateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthenticationV1Server).Validate(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/authentication.AuthenticationV1/Validate",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthenticationV1Server).Validate(ctx, req.(*ValidateRequest))
}
return interceptor(ctx, in, info, handler)
}
func _AuthenticationV1_CreateToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthenticationV1Server).CreateToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/authentication.AuthenticationV1/CreateToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthenticationV1Server).CreateToken(ctx, req.(*CreateTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
// AuthenticationV1_ServiceDesc is the grpc.ServiceDesc for AuthenticationV1 service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var AuthenticationV1_ServiceDesc = grpc.ServiceDesc{
ServiceName: "authentication.AuthenticationV1",
HandlerType: (*AuthenticationV1Server)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Validate",
Handler: _AuthenticationV1_Validate_Handler,
},
{
MethodName: "CreateToken",
Handler: _AuthenticationV1_CreateToken_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "integrations/authentication/v1/definition/definition.proto",
}

View file

@ -0,0 +1,204 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"context"
"sync"
"time"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/durationpb"
pbAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/strings"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
"github.com/arangodb/kube-arangodb/pkg/util/token"
)
func New(ctx context.Context, cfg Configuration) (svc.Handler, error) {
return newInternal(ctx, cfg)
}
func newInternal(ctx context.Context, cfg Configuration) (*implementation, error) {
if err := cfg.Validate(); err != nil {
return nil, err
}
obj := &implementation{
cfg: cfg,
ctx: ctx,
}
return obj, nil
}
var _ pbAuthenticationV1.AuthenticationV1Server = &implementation{}
var _ svc.Handler = &implementation{}
type implementation struct {
pbAuthenticationV1.UnimplementedAuthenticationV1Server
lock sync.RWMutex
ctx context.Context
cfg Configuration
cache *cache
}
func (i *implementation) Name() string {
return "authentication.v1"
}
func (i *implementation) Health() svc.HealthState {
return svc.Healthy
}
func (i *implementation) Register(registrar *grpc.Server) {
pbAuthenticationV1.RegisterAuthenticationV1Server(registrar, i)
}
func (i *implementation) Validate(ctx context.Context, request *pbAuthenticationV1.ValidateRequest) (*pbAuthenticationV1.ValidateResponse, error) {
if request == nil {
return nil, errors.Errorf("Request is nil")
}
if !i.cfg.Enabled {
return &pbAuthenticationV1.ValidateResponse{
IsValid: true,
Details: &pbAuthenticationV1.ValidateResponseDetails{
Lifetime: durationpb.New(DefaultTokenMaxTTL),
User: DefaultAdminUser,
},
}, nil
}
cache, err := i.withCache()
if err != nil {
return nil, err
}
user, exp, err := i.extractTokenDetails(cache, request.GetToken())
if err != nil {
return &pbAuthenticationV1.ValidateResponse{
IsValid: false,
Message: err.Error(),
}, nil
}
return &pbAuthenticationV1.ValidateResponse{
IsValid: true,
Details: &pbAuthenticationV1.ValidateResponseDetails{
Lifetime: durationpb.New(exp),
User: user,
},
}, nil
}
func (i *implementation) CreateToken(ctx context.Context, request *pbAuthenticationV1.CreateTokenRequest) (*pbAuthenticationV1.CreateTokenResponse, error) {
if request == nil {
return nil, errors.Errorf("Request is nil")
}
if !i.cfg.Enabled {
// Authentication is not enabled, pass with empty token
return &pbAuthenticationV1.CreateTokenResponse{
Lifetime: durationpb.New(DefaultTokenMaxTTL),
User: DefaultAdminUser,
Token: "",
}, nil
}
cache, err := i.withCache()
if err != nil {
return nil, err
}
user := util.TypeOrDefault(request.User, i.cfg.Create.DefaultUser)
duration := i.cfg.Create.DefaultTTL
if v := request.Lifetime; v != nil {
duration = v.AsDuration()
}
// Check configuration
if v := i.cfg.Create.AllowedUsers; len(v) > 0 {
if !strings.ListContains(v, user) {
return nil, errors.Errorf("User %s is not allowed", user)
}
}
if v := i.cfg.Create.MaxTTL; duration > v {
duration = v
}
if v := i.cfg.Create.MinTTL; duration < v {
duration = v
}
// Token is validated, we can continue with creation
secret := cache.signingToken
signedToken, err := token.New(secret, token.NewClaims().With(token.WithDefaultClaims(), token.WithCurrentIAT(), token.WithDuration(duration), token.WithUsername(user)))
if err != nil {
return nil, err
}
user, exp, err := i.extractTokenDetails(cache, signedToken)
if err != nil {
return nil, err
}
return &pbAuthenticationV1.CreateTokenResponse{
Lifetime: durationpb.New(exp),
User: user,
Token: signedToken,
}, nil
}
func (i *implementation) extractTokenDetails(cache *cache, t string) (string, time.Duration, error) {
// Let's check if token is signed properly
p, err := token.ParseWithAny(t, cache.validationTokens...)
if err != nil {
return "", 0, err
}
user := DefaultAdminUser
if v, ok := p[token.ClaimPreferredUsername]; ok {
if s, ok := v.(string); ok {
user = s
}
}
duration := DefaultTokenMaxTTL
if v, ok := p[token.ClaimEXP]; ok {
if s, ok := v.(int64); ok {
duration = time.Until(time.Unix(s, 0))
}
}
return user, duration, nil
}

View file

@ -0,0 +1,184 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/durationpb"
pbAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition"
"github.com/arangodb/kube-arangodb/pkg/util"
)
func Test_Basic(t *testing.T) {
directory := t.TempDir()
reSaveJWTTokens(t, directory, generateJWTToken(), generateJWTToken(), generateJWTToken(), generateJWTToken(), generateJWTToken(), generateJWTToken())
ctx, c := context.WithCancel(context.Background())
defer c()
s, err := newInternal(ctx, Configuration{
Path: directory,
TTL: time.Duration(0),
})
require.NoError(t, err)
// Create token
tokenResponse, err := s.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{
Lifetime: durationpb.New(time.Minute),
User: util.NewType(DefaultUser),
})
require.NoError(t, err)
validateResponse, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: tokenResponse.Token,
})
require.NoError(t, err)
require.True(t, validateResponse.IsValid)
require.NotNil(t, validateResponse.Details)
require.EqualValues(t, DefaultUser, validateResponse.Details.User)
}
func Test_Flow_WithoutTTL(t *testing.T) {
directory := t.TempDir()
ctx, c := context.WithCancel(context.Background())
defer c()
cfg := NewConfiguration()
cfg.Path = directory
cfg.TTL = time.Duration(0)
s, err := newInternal(ctx, cfg)
require.NoError(t, err)
secret1 := generateJWTToken()
secret2 := generateJWTToken()
var token1, token2 string
t.Run("Ensure we cant work without secrets", func(t *testing.T) {
_, err := s.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{})
require.EqualError(t, err, "unexpected EOF")
})
t.Run("Save secret1", func(t *testing.T) {
reSaveJWTTokens(t, directory, secret1)
})
t.Run("Create token1", func(t *testing.T) {
response, err := s.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{})
require.NoError(t, err)
require.NotNil(t, response)
token1 = response.Token
})
t.Run("Validate token1", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token1,
})
require.NoError(t, err)
require.NotNil(t, response)
require.True(t, response.IsValid)
require.EqualValues(t, cfg.Create.DefaultUser, response.Details.User)
})
t.Run("Save secret2", func(t *testing.T) {
reSaveJWTTokens(t, directory, secret2)
})
t.Run("Create token2", func(t *testing.T) {
response, err := s.CreateToken(context.Background(), &pbAuthenticationV1.CreateTokenRequest{})
require.NoError(t, err)
require.NotNil(t, response)
token2 = response.Token
})
t.Run("Validate token2", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token2,
})
require.NoError(t, err)
require.NotNil(t, response)
require.True(t, response.IsValid)
require.EqualValues(t, cfg.Create.DefaultUser, response.Details.User)
})
t.Run("Save secret1", func(t *testing.T) {
reSaveJWTTokens(t, directory, secret1)
})
t.Run("Validate token2", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token2,
})
require.NoError(t, err)
require.NotNil(t, response)
require.False(t, response.IsValid)
require.EqualValues(t, "signature is invalid", response.Message)
})
t.Run("Save secret2", func(t *testing.T) {
reSaveJWTTokens(t, directory, secret2)
})
t.Run("Validate token1", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token1,
})
require.NoError(t, err)
require.NotNil(t, response)
require.False(t, response.IsValid)
require.EqualValues(t, "signature is invalid", response.Message)
})
t.Run("Save secret1 & secret2", func(t *testing.T) {
reSaveJWTTokens(t, directory, secret1, secret2)
})
t.Run("Validate token1", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token1,
})
require.NoError(t, err)
require.NotNil(t, response)
require.True(t, response.IsValid)
require.EqualValues(t, cfg.Create.DefaultUser, response.Details.User)
})
t.Run("Validate token2", func(t *testing.T) {
response, err := s.Validate(context.Background(), &pbAuthenticationV1.ValidateRequest{
Token: token2,
})
require.NoError(t, err)
require.NotNil(t, response)
require.True(t, response.IsValid)
require.EqualValues(t, cfg.Create.DefaultUser, response.Details.User)
})
}

View file

@ -0,0 +1,191 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"context"
"testing"
"github.com/stretchr/testify/require"
pbAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1/definition"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
"github.com/arangodb/kube-arangodb/pkg/util/tests/tgrpc"
)
func Handler(t *testing.T, ctx context.Context, mods ...Mod) svc.Handler {
handler, err := New(ctx, NewConfiguration().With(mods...))
require.NoError(t, err)
return handler
}
func Client(t *testing.T, ctx context.Context, mods ...Mod) (pbAuthenticationV1.AuthenticationV1Client, string) {
directory := t.TempDir()
var currentMods []Mod
currentMods = append(currentMods, func(c Configuration) Configuration {
c.Path = directory
return c
})
currentMods = append(currentMods, mods...)
local := svc.NewService(svc.Configuration{
Address: "127.0.0.1:0",
}, Handler(t, ctx, currentMods...))
start := local.Start(ctx)
client := tgrpc.NewGRPCClient(t, ctx, pbAuthenticationV1.NewAuthenticationV1Client, start.Address())
return client, directory
}
func Test_Service(t *testing.T) {
ctx, c := context.WithCancel(context.Background())
defer c()
client, directory := Client(t, ctx)
reSaveJWTTokens(t, directory, generateJWTToken())
token, err := client.CreateToken(ctx, &pbAuthenticationV1.CreateTokenRequest{})
require.NoError(t, err)
t.Logf("Token generated for user %s: %s", token.User, token.Token)
require.EqualValues(t, "root", token.User)
valid, err := client.Validate(ctx, &pbAuthenticationV1.ValidateRequest{
Token: token.Token,
})
require.NoError(t, err)
require.True(t, valid.IsValid)
require.NotNil(t, valid.Details)
require.EqualValues(t, token.User, valid.Details.User)
}
func Test_Service_DifferentDefaultUser(t *testing.T) {
ctx, c := context.WithCancel(context.Background())
defer c()
client, directory := Client(t, ctx, func(c Configuration) Configuration {
c.Create.DefaultUser = "different"
return c
})
reSaveJWTTokens(t, directory, generateJWTToken())
token, err := client.CreateToken(ctx, &pbAuthenticationV1.CreateTokenRequest{})
require.NoError(t, err)
t.Logf("Token generated for user %s: %s", token.User, token.Token)
require.EqualValues(t, "different", token.User)
valid, err := client.Validate(ctx, &pbAuthenticationV1.ValidateRequest{
Token: token.Token,
})
require.NoError(t, err)
require.True(t, valid.IsValid)
require.NotNil(t, valid.Details)
require.EqualValues(t, token.User, valid.Details.User)
}
func Test_Service_AskForDefaultIfAllowed(t *testing.T) {
ctx, c := context.WithCancel(context.Background())
defer c()
client, directory := Client(t, ctx, func(c Configuration) Configuration {
c.Create.AllowedUsers = []string{"root"}
return c
})
reSaveJWTTokens(t, directory, generateJWTToken())
token, err := client.CreateToken(ctx, &pbAuthenticationV1.CreateTokenRequest{})
require.NoError(t, err)
t.Logf("Token generated for user %s: %s", token.User, token.Token)
require.EqualValues(t, "root", token.User)
valid, err := client.Validate(ctx, &pbAuthenticationV1.ValidateRequest{
Token: token.Token,
})
require.NoError(t, err)
require.True(t, valid.IsValid)
require.NotNil(t, valid.Details)
require.EqualValues(t, token.User, valid.Details.User)
}
func Test_Service_AskForNonDefaultIfAllowed(t *testing.T) {
ctx, c := context.WithCancel(context.Background())
defer c()
client, directory := Client(t, ctx, func(c Configuration) Configuration {
c.Create.AllowedUsers = []string{"root", "other"}
return c
})
reSaveJWTTokens(t, directory, generateJWTToken())
token, err := client.CreateToken(ctx, &pbAuthenticationV1.CreateTokenRequest{
User: util.NewType("other"),
})
require.NoError(t, err)
t.Logf("Token generated for user %s: %s", token.User, token.Token)
require.EqualValues(t, "other", token.User)
valid, err := client.Validate(ctx, &pbAuthenticationV1.ValidateRequest{
Token: token.Token,
})
require.NoError(t, err)
require.True(t, valid.IsValid)
require.NotNil(t, valid.Details)
require.EqualValues(t, token.User, valid.Details.User)
}
func Test_Service_AskForDefaultIfBlocked(t *testing.T) {
ctx, c := context.WithCancel(context.Background())
defer c()
client, directory := Client(t, ctx, func(c Configuration) Configuration {
c.Create.AllowedUsers = []string{"root"}
return c
})
reSaveJWTTokens(t, directory, generateJWTToken())
_, err := client.CreateToken(ctx, &pbAuthenticationV1.CreateTokenRequest{
User: util.NewType("blocked"),
})
require.EqualError(t, err, "rpc error: code = Unknown desc = User blocked is not allowed")
}

View file

@ -0,0 +1,71 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package v1
import (
"os"
"path"
"testing"
"github.com/stretchr/testify/require"
"github.com/arangodb/kube-arangodb/pkg/util"
)
type tokenType [32]byte
func generateJWTToken() tokenType {
var tokenData tokenType
util.Rand().Read(tokenData[:])
return tokenData
}
func reSaveJWTTokens(t *testing.T, directory string, datas ...tokenType) {
cleanJWTTokens(t, directory)
saveJWTTokens(t, directory, datas...)
}
func cleanJWTTokens(t *testing.T, directory string) {
files, err := os.ReadDir(directory)
require.NoError(t, err)
for _, f := range files {
require.NoError(t, os.Remove(path.Join(directory, f.Name())))
}
files, err = os.ReadDir(directory)
require.NoError(t, err)
require.Len(t, files, 0)
}
func saveJWTTokens(t *testing.T, directory string, datas ...tokenType) {
require.True(t, len(datas) > 0, "Required at least one token")
saveJWTToken(t, directory, "-", datas[0])
for _, data := range datas {
saveJWTToken(t, directory, util.SHA256(data[:]), data)
}
}
func saveJWTToken(t *testing.T, directory, name string, data tokenType) {
fn := path.Join(directory, name)
require.NoError(t, os.WriteFile(fn, data[:], 0644))
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@ import (
)
func Init(cmd *cobra.Command) error {
f := cmd.PersistentFlags()
f := cmd.Flags()
f.Bool("agency.poll-enabled", false, "The Agency poll functionality enablement (EnterpriseEdition Only)")

View file

@ -49,6 +49,7 @@ import (
secretv1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret/v1"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tls"
"github.com/arangodb/kube-arangodb/pkg/util/token"
)
var (
@ -422,7 +423,7 @@ func AppendKeyfileToKeyfolder(ctx context.Context, cachedStatus inspectorInterfa
var (
exporterTokenClaims = jg.MapClaims{
"iss": "arangodb",
token.ClaimISS: token.ClaimISSValue,
"server_id": "exporter",
"allowed_paths": []interface{}{"/_admin/statistics", "/_admin/statistics-description",
shared.ArangoExporterInternalEndpoint, shared.ArangoExporterInternalEndpointV2,

View file

@ -0,0 +1,67 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package integrations
import (
"context"
"github.com/spf13/cobra"
pbImplAuthenticationV1 "github.com/arangodb/kube-arangodb/integrations/authentication/v1"
"github.com/arangodb/kube-arangodb/pkg/util/svc"
)
func init() {
register(func() Integration {
return &authenticationV1{}
})
}
type authenticationV1 struct {
config pbImplAuthenticationV1.Configuration
}
func (a *authenticationV1) Register(cmd *cobra.Command, arg ArgGen) error {
f := cmd.Flags()
f.StringVar(&a.config.Path, arg("path"), "", "Path to the JWT Folder")
f.BoolVar(&a.config.Enabled, arg("enabled"), true, "Defines if Authentication is enabled")
f.DurationVar(&a.config.TTL, arg("ttl"), pbImplAuthenticationV1.DefaultTTL, "TTL of the JWT cache")
f.StringVar(&a.config.Create.DefaultUser, arg("token.user"), pbImplAuthenticationV1.DefaultUser, "Default user of the Token")
f.DurationVar(&a.config.Create.DefaultTTL, arg("token.ttl.default"), pbImplAuthenticationV1.DefaultTokenDefaultTTL, "Default Token TTL")
f.DurationVar(&a.config.Create.MinTTL, arg("token.ttl.min"), pbImplAuthenticationV1.DefaultTokenMinTTL, "Min Token TTL")
f.DurationVar(&a.config.Create.MaxTTL, arg("token.ttl.max"), pbImplAuthenticationV1.DefaultTokenMaxTTL, "Max Token TTL")
f.StringSliceVar(&a.config.Create.AllowedUsers, arg("token.allowed"), []string{}, "Allowed users for the Token")
return nil
}
func (a *authenticationV1) Handler(ctx context.Context) (svc.Handler, error) {
return pbImplAuthenticationV1.New(ctx, a.config)
}
func (a *authenticationV1) Name() string {
return "authentication.v1"
}
func (a *authenticationV1) Description() string {
return "Enable AuthenticationV1 Integration Service"
}

View file

@ -77,12 +77,9 @@ func (c *configuration) Register(cmd *cobra.Command) error {
return c.registered[i].Name() < c.registered[j].Name()
})
subCommand := &cobra.Command{
Use: "integration",
RunE: c.run,
}
cmd.RunE = c.run
f := subCommand.Flags()
f := cmd.Flags()
f.StringVar(&c.health.config.Address, "health.address", "0.0.0.0:9091", "Address to expose health service")
f.BoolVar(&c.health.shutdownEnabled, "health.shutdown.enabled", true, "Determines if shutdown service should be enabled and exposed")
@ -93,14 +90,13 @@ func (c *configuration) Register(cmd *cobra.Command) error {
f.Bool(prefix, false, service.Description())
if err := service.Register(subCommand, func(name string) string {
if err := service.Register(cmd, func(name string) string {
return fmt.Sprintf("%s.%s", prefix, name)
}); err != nil {
return errors.Wrapf(err, "Unable to register service %s", service.Name())
}
}
cmd.AddCommand(subCommand)
return nil
}

55
pkg/ml/container_jwt.go Normal file
View file

@ -0,0 +1,55 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package ml
import (
core "k8s.io/api/core/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
)
func AddJWTFolderToPod(deployment *api.ArangoDeployment, spec *core.PodTemplateSpec, integrationContainer *core.Container) {
if deployment.GetAcceptedSpec().Authentication.IsAuthenticated() {
spec.Spec.Volumes = append(spec.Spec.Volumes, core.Volume{
Name: shared.ClusterJWTSecretVolumeName,
VolumeSource: core.VolumeSource{
Secret: &core.SecretVolumeSource{
SecretName: pod.JWTSecretFolder(deployment.GetName()),
},
},
})
} else {
spec.Spec.Volumes = append(spec.Spec.Volumes, core.Volume{
Name: shared.ClusterJWTSecretVolumeName,
VolumeSource: core.VolumeSource{
EmptyDir: &core.EmptyDirVolumeSource{},
},
})
}
integrationContainer.VolumeMounts = append(integrationContainer.VolumeMounts, core.VolumeMount{
Name: shared.ClusterJWTSecretVolumeName,
ReadOnly: true,
MountPath: shared.ClusterJWTSecretVolumeMountDir,
})
}

63
pkg/util/file.go Normal file
View file

@ -0,0 +1,63 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package util
import (
"io"
"os"
"github.com/pkg/errors"
)
func OpenWithRead(path string, size int) ([]byte, error) {
f, err := os.OpenFile(path, os.O_RDONLY, 0644)
if err != nil {
return nil, err
}
buff := make([]byte, size+1)
if s, err := Read(f, buff); err != nil {
if nerr := f.Close(); nerr != nil {
return nil, nerr
}
return nil, err
} else if s == 0 {
return nil, io.ErrUnexpectedEOF
} else {
return buff[:s], nil
}
}
func Read(in io.Reader, buff []byte) (int, error) {
readed := 0
for {
s, err := in.Read(buff)
readed += s
if err != nil {
if errors.Is(err, io.EOF) {
return readed, nil
}
return readed, err
}
}
}

View file

@ -23,7 +23,6 @@ package k8sutil
import (
"context"
jg "github.com/golang-jwt/jwt"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -35,6 +34,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/globals"
secretv1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret/v1"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
"github.com/arangodb/kube-arangodb/pkg/util/token"
)
// ValidateEncryptionKeySecret checks that a secret with given name in given namespace
@ -302,12 +302,8 @@ func CreateJWTFromSecret(ctx context.Context, cachedSecrets secretv1.ReadInterfa
if err != nil {
return errors.WithStack(err)
}
// Create a new token object, specifying signing method and the claims
// you would like it to contain.
token := jg.NewWithClaims(jg.SigningMethodHS256, jg.MapClaims(claims))
// Sign and get the complete encoded token as a string using the secret
signedToken, err := token.SignedString([]byte(secret))
signedToken, err := token.New([]byte(secret), claims)
if err != nil {
return errors.WithStack(err)
}

View file

@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -28,6 +28,16 @@ import (
"golang.org/x/text/language"
)
func ListContains(a []string, b string) bool {
for _, v := range a {
if v == b {
return true
}
}
return false
}
func CompareStrings(a, b string) bool {
return a == b
}

46
pkg/util/token/errors.go Normal file
View file

@ -0,0 +1,46 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package token
import (
jg "github.com/golang-jwt/jwt"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
func IsSignatureInvalidError(err error) bool {
return isJQError(err, jg.ErrSignatureInvalid)
}
func isJQError(err, expected error) bool {
if err == nil || expected == nil {
return false
}
var v *jg.ValidationError
if errors.As(err, &v) {
if errors.Is(v.Inner, expected) {
return true
}
}
return false
}

78
pkg/util/token/mods.go Normal file
View file

@ -0,0 +1,78 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package token
import (
"time"
jg "github.com/golang-jwt/jwt"
)
var defaultTokenClaims = jg.MapClaims{
ClaimISS: ClaimISSValue,
}
func WithDefaultClaims() Mod {
return func(in Claims) Claims {
for k, v := range defaultTokenClaims {
if _, ok := in[k]; !ok {
in[k] = v
}
}
return in
}
}
func WithUsername(username string) Mod {
return func(in Claims) Claims {
in[ClaimPreferredUsername] = username
return in
}
}
func WithCurrentIAT() Mod {
return func(in Claims) Claims {
in[ClaimIAT] = time.Now().Unix()
return in
}
}
func WithIAT(time time.Time) Mod {
return func(in Claims) Claims {
in[ClaimIAT] = time.Unix()
return in
}
}
func WithDuration(dur time.Duration) Mod {
return func(in Claims) Claims {
in[ClaimEXP] = time.Now().Add(dur).Unix()
return in
}
}
func WithExp(time time.Time) Mod {
return func(in Claims) Claims {
in[ClaimEXP] = time.Unix()
return in
}
}

63
pkg/util/token/parse.go Normal file
View file

@ -0,0 +1,63 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package token
import (
jg "github.com/golang-jwt/jwt"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
func Parse(token string, secret []byte) (Claims, error) {
parsedToken, err := jg.Parse(token, func(token *jg.Token) (i interface{}, err error) {
return secret, nil
})
if err != nil {
return nil, err
}
tokenClaims, ok := parsedToken.Claims.(jg.MapClaims)
if !ok {
return nil, errors.Errorf("Invalid token provided")
}
return Claims(tokenClaims), nil
}
func ParseWithAny(token string, secrets ...[]byte) (Claims, error) {
for _, secret := range secrets {
if c, err := Parse(token, secret); err != nil {
if IsSignatureInvalidError(err) {
continue
}
return nil, err
} else {
return c, nil
}
}
return nil, &jg.ValidationError{
Inner: jg.ErrSignatureInvalid,
Errors: 1,
}
}

69
pkg/util/token/token.go Normal file
View file

@ -0,0 +1,69 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package token
import (
jg "github.com/golang-jwt/jwt"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
)
const (
ClaimISS = "iss"
ClaimISSValue = "arangodb"
ClaimEXP = "exp"
ClaimIAT = "iat"
ClaimPreferredUsername = "preferred_username"
)
type Mod func(in Claims) Claims
func NewClaims() Claims {
return Claims{}
}
type Claims jg.MapClaims
func (t Claims) With(mods ...Mod) Claims {
q := t
if q == nil {
q = Claims{}
}
for _, mod := range mods {
q = mod(q)
}
return q
}
func New(secret []byte, claims map[string]interface{}) (string, error) {
token := jg.NewWithClaims(jg.SigningMethodHS256, jg.MapClaims(claims))
// Sign and get the complete encoded token as a string using the secret
signedToken, err := token.SignedString(secret)
if err != nil {
return "", errors.WithStack(err)
}
return signedToken, nil
}

View file

@ -0,0 +1,129 @@
//
// DISCLAIMER
//
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
package token
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/arangodb/kube-arangodb/pkg/util"
)
func secret() []byte {
d := make([]byte, 32)
util.Rand().Read(d)
return d
}
func sign(t *testing.T, secret []byte, mods ...Mod) string {
token, err := New(secret, NewClaims().With(mods...))
require.NoError(t, err)
return token
}
func Test_TokenSign(t *testing.T) {
t.Run("Signed properly token", func(t *testing.T) {
s := secret()
token := sign(t, s, WithCurrentIAT())
claims, err := Parse(token, s)
require.NoError(t, err)
require.Contains(t, claims, ClaimIAT)
})
t.Run("Signed in future token", func(t *testing.T) {
s := secret()
token := sign(t, s, WithIAT(time.Now().Add(time.Hour)))
_, err := Parse(token, s)
require.EqualError(t, err, "Token used before issued")
})
t.Run("Expired", func(t *testing.T) {
s := secret()
token := sign(t, s, WithIAT(time.Now().Add(-time.Hour)), WithDuration(-time.Second))
_, err := Parse(token, s)
require.EqualError(t, err, "Token is expired")
})
t.Run("Invalid secret", func(t *testing.T) {
s := secret()
s2 := secret()
token := sign(t, s, WithCurrentIAT())
_, err := Parse(token, s2)
require.EqualError(t, err, "signature is invalid")
require.True(t, IsSignatureInvalidError(err))
})
t.Run("Signed properly token with first", func(t *testing.T) {
s := secret()
s2 := secret()
token := sign(t, s, WithCurrentIAT())
claims, err := ParseWithAny(token, s, s2)
require.NoError(t, err)
require.Contains(t, claims, ClaimIAT)
})
t.Run("Signed properly token with second", func(t *testing.T) {
s := secret()
s2 := secret()
token := sign(t, s, WithCurrentIAT())
claims, err := ParseWithAny(token, s2, s)
require.NoError(t, err)
require.Contains(t, claims, ClaimIAT)
})
t.Run("Without secrets", func(t *testing.T) {
s := secret()
token := sign(t, s, WithCurrentIAT())
_, err := ParseWithAny(token)
require.True(t, IsSignatureInvalidError(err))
})
t.Run("Expired with second", func(t *testing.T) {
s := secret()
s2 := secret()
token := sign(t, s, WithIAT(time.Now().Add(-time.Hour)), WithDuration(-time.Second))
_, err := ParseWithAny(token, s2, s)
require.EqualError(t, err, "Token is expired")
})
}