Metadata parser: add support for built-in authentication profiles and metadata properties (#2760)
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com> Co-authored-by: Bernd Verst <github@bernd.dev>
This commit is contained in:
parent
8a4d7b8542
commit
5dad8a867c
|
@ -8,7 +8,7 @@ The CLI is written in Go and based on the [cobra](https://github.com/spf13/cobra
|
|||
|
||||
You have two ways to run the CLI:
|
||||
|
||||
1. Within the `build-tools` directly, you can run the CLI with `go run .` directly. For example `go run . help` shows the help page.
|
||||
1. Within the `build-tools` directory, you can run the CLI with `go run .` directly. For example `go run . help` shows the help page.
|
||||
2. You can build a pre-compiled binary by running `make compile-build-tools` in the root folder of this repository. This will build an executable called `build-tools` (or `build-tools.exe` on Windows) in the `build-tools` folder. You can then run the command directly, for example `./build-tools help`
|
||||
|
||||
## Available commands
|
||||
|
|
|
@ -3,18 +3,24 @@ module github.com/dapr/components-contrib/build-tools
|
|||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/dapr/components-contrib v0.0.0
|
||||
github.com/invopop/jsonschema v0.6.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dapr/kit v0.0.5-0.20230401092230-30d122f67bdc // indirect
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/testify v1.8.2 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dapr/components-contrib => ../
|
||||
|
|
|
@ -1,29 +1,35 @@
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/dapr/kit v0.0.5-0.20230401092230-30d122f67bdc h1:VZ+VUTUc1baDyTkvdTRnW1rOKnPwLe+3K5kLncMLe74=
|
||||
github.com/dapr/kit v0.0.5-0.20230401092230-30d122f67bdc/go.mod h1:uKuSJi2Ofj02OixDrpzCFKk+lETrQxQtVIra+wfyzsw=
|
||||
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/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/jsonschema v0.6.0 h1:8e+xY8ZEn8gDHUYylSlLHy22P+SLeIRIHv3nM3hCbmY=
|
||||
github.com/invopop/jsonschema v0.6.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY=
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
|
@ -31,11 +37,12 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
|
|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5 h1:ImnGIsrcG8vwbovhYvvSY8fagVV6QhCWSWXfzwGDLVs=
|
||||
github.com/xeipuuv/gojsonschema v1.2.1-0.20201027075954-b076d39a02e5/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
|
|
|
@ -20,9 +20,10 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/dapr/components-contrib/build-tools/pkg/metadataschema"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/dapr/components-contrib/build-tools/pkg/metadataschema"
|
||||
)
|
||||
|
||||
// Parser used to parse and validate component metadata YAML or JSON files.
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/dapr/kit/logger"
|
||||
{{range $fullpkg, $val := .Pkgs}}
|
||||
"github.com/dapr/kit/logger"
|
||||
mdutils "github.com/dapr/components-contrib/metadata"
|
||||
|
||||
{{- range $fullpkg, $val := .Pkgs }}
|
||||
{{index $val 0}} "{{print "github.com/dapr/components-contrib/" $fullpkg}}"
|
||||
{{end}}
|
||||
{{- end}}
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -22,9 +24,13 @@ func main() {
|
|||
basePath := os.Args[1]
|
||||
log := logger.NewLogger("metadata")
|
||||
|
||||
var yamlMetadata *map[string]string
|
||||
var missing map[string]string
|
||||
missingByComponent := make(map[string]map[string]string)
|
||||
var (
|
||||
yamlMetadata *map[string]string
|
||||
missing map[string]string
|
||||
unexpected []string
|
||||
)
|
||||
missingByComponent := make(map[string]map[string]string)
|
||||
unexpectedByComponent := make(map[string][]string)
|
||||
|
||||
{{range $fullpkg, $val := .Pkgs}}
|
||||
instanceOf_{{index $val 0}} := {{index $val 0}}.{{index $val 1}}(log)
|
||||
|
@ -34,18 +40,36 @@ func main() {
|
|||
if len(missing) > 0 {
|
||||
missingByComponent["{{$fullpkg}}"] = missing
|
||||
}
|
||||
if yamlMetadata != nil && len(*yamlMetadata) > 0 {
|
||||
unexpected = checkUnexpectedBuiltinMetadata(*yamlMetadata, mdutils.ComponentType("{{index $val 2}}"))
|
||||
if len(unexpected) > 0 {
|
||||
unexpectedByComponent["{{$fullpkg}}"] = unexpected
|
||||
}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
jsonData, err := json.MarshalIndent(missingByComponent, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if len(missingByComponent) > 0 {
|
||||
fmt.Println("The following components are missing metadata in their metadata.yaml:\n")
|
||||
fmt.Println(string(jsonData))
|
||||
os.Exit(1)
|
||||
}
|
||||
var failed bool
|
||||
if len(missingByComponent) > 0 {
|
||||
failed = true
|
||||
jsonData, err := json.MarshalIndent(missingByComponent, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("The following components are missing metadata in their metadata.yaml:")
|
||||
fmt.Println(string(jsonData))
|
||||
}
|
||||
if len(unexpectedByComponent) > 0 {
|
||||
failed = true
|
||||
jsonData, err := json.MarshalIndent(unexpectedByComponent, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("The following components have unexpected metadata in their metadata.yaml:")
|
||||
fmt.Println(string(jsonData))
|
||||
}
|
||||
if failed {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
|
@ -53,6 +77,9 @@ type Data struct {
|
|||
AuthenticationProfiles []struct {
|
||||
Metadata []Metadata `yaml:"metadata"`
|
||||
} `yaml:"authenticationProfiles"`
|
||||
BuiltinAuthenticationProfiles []struct {
|
||||
Metadata []Metadata `yaml:"metadata"`
|
||||
} `yaml:"builtinAuthenticationProfiles"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
|
@ -89,17 +116,24 @@ func getYamlMetadata(basePath string, pkg string) *map[string]string {
|
|||
}
|
||||
}
|
||||
}
|
||||
for _, bi := range d.BuiltinAuthenticationProfiles {
|
||||
for _, m := range bi.Metadata {
|
||||
names[strings.ToLower(m.Name)] = "string"
|
||||
if m.Type != "" {
|
||||
names[strings.ToLower(m.Name)] = m.Type
|
||||
}
|
||||
}
|
||||
}
|
||||
return &names
|
||||
}
|
||||
|
||||
func checkMissingMetadata(yamlMetadataP *map[string]string, componentMetadata map[string]string) map[string]string {
|
||||
func checkMissingMetadata(yamlMetadata *map[string]string, componentMetadata map[string]string) map[string]string {
|
||||
missingMetadata := make(map[string]string)
|
||||
// if there is no yaml metadata, then we are not missing anything yet
|
||||
if yamlMetadataP != nil {
|
||||
yamlMetadata := *yamlMetadataP
|
||||
if yamlMetadata != nil && len(*yamlMetadata) > 0 {
|
||||
for key := range componentMetadata {
|
||||
lowerKey := strings.ToLower(key)
|
||||
if _, ok := yamlMetadata[lowerKey]; !ok {
|
||||
if _, ok := (*yamlMetadata)[lowerKey]; !ok {
|
||||
missingMetadata[lowerKey] = componentMetadata[key]
|
||||
}
|
||||
// todo - check if the metadata is the same data type
|
||||
|
@ -107,3 +141,16 @@ func checkMissingMetadata(yamlMetadataP *map[string]string, componentMetadata ma
|
|||
}
|
||||
return missingMetadata
|
||||
}
|
||||
|
||||
func checkUnexpectedBuiltinMetadata(yamlMetadata map[string]string, compType mdutils.ComponentType) []string {
|
||||
unexpected := []string{}
|
||||
builtin := compType.BuiltInMetadataProperties()
|
||||
for _, k := range builtin {
|
||||
k = strings.ToLower(k)
|
||||
_, ok := yamlMetadata[k]
|
||||
if ok {
|
||||
unexpected = append(unexpected, k)
|
||||
}
|
||||
}
|
||||
return unexpected
|
||||
}
|
||||
|
|
|
@ -12,11 +12,22 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
// Import the embed package.
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed analyzer.template
|
||||
var tmpl string
|
||||
|
||||
type PkgInfo struct {
|
||||
Method string
|
||||
ComponentType string
|
||||
}
|
||||
|
||||
func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, outputfile string) {
|
||||
fset := token.NewFileSet()
|
||||
pkgs := make(map[string]string)
|
||||
pkgs := make(map[string]PkgInfo)
|
||||
|
||||
err := filepath.WalkDir(contribRoot, func(path string, file fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
|
@ -34,7 +45,7 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
return nil
|
||||
}
|
||||
|
||||
componentType := ""
|
||||
componentTypeFolder := ""
|
||||
packageName := ""
|
||||
skip := true
|
||||
dir := filepath.Dir(path)
|
||||
|
@ -51,7 +62,7 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
|
||||
for _, val := range componentFolders {
|
||||
if curFolder == val {
|
||||
componentType = curFolder
|
||||
componentTypeFolder = curFolder
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,8 +77,9 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
var methodFinderErr error
|
||||
methodFound := false
|
||||
|
||||
switch componentType {
|
||||
switch componentTypeFolder {
|
||||
// Only the component types listed here implement the GetComponentMetadata method today
|
||||
// Note: these are folder names not the type of components
|
||||
case "secretstores":
|
||||
method, methodFinderErr = getConstructorMethod("secretstores.SecretStore", parsedFile)
|
||||
if methodFinderErr == nil {
|
||||
|
@ -126,7 +138,10 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
}
|
||||
|
||||
if methodFound {
|
||||
pkgs[packageName] = method
|
||||
pkgs[packageName] = PkgInfo{
|
||||
Method: method,
|
||||
ComponentType: componentTypeFolder,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -137,9 +152,9 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
|
||||
data := make(map[string][]string)
|
||||
|
||||
for fullpkg, method := range pkgs {
|
||||
for fullpkg, info := range pkgs {
|
||||
sanitizedPkg := strings.ReplaceAll(strings.ReplaceAll(fullpkg, "/", "_"), "-", "_")
|
||||
data[fullpkg] = []string{sanitizedPkg, method}
|
||||
data[fullpkg] = []string{sanitizedPkg, info.Method, info.ComponentType}
|
||||
}
|
||||
|
||||
templateData := struct {
|
||||
|
@ -149,22 +164,16 @@ func GenerateMetadataAnalyzer(contribRoot string, componentFolders []string, out
|
|||
}
|
||||
|
||||
// let's try loading the template
|
||||
bytes, fileErr := os.ReadFile(".build-tools/pkg/metadataanalyzer/analyzer.template")
|
||||
tmpl := string(bytes)
|
||||
if fileErr != nil {
|
||||
log.Fatal(fileErr)
|
||||
}
|
||||
|
||||
f, err := os.Create(outputfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
t := template.Must(template.New("tmpl").Parse(tmpl))
|
||||
err = t.Execute(f, templateData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Copyright 2022 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package metadataschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ParseBuiltinAuthenticationProfile returns an AuthenticationProfile(s) from a given BuiltinAuthenticationProfile.
|
||||
func ParseBuiltinAuthenticationProfile(bi BuiltinAuthenticationProfile) ([]AuthenticationProfile, error) {
|
||||
switch bi.Name {
|
||||
case "azuread":
|
||||
profiles := []AuthenticationProfile{
|
||||
{
|
||||
Title: "Azure AD: Managed identity",
|
||||
Description: "Authenticate using Azure AD and a managed identity.",
|
||||
Metadata: mergedMetadata(bi.Metadata,
|
||||
Metadata{
|
||||
Name: "azureClientId",
|
||||
Description: "Client ID (application ID). Required if the service has multiple identities assigned.",
|
||||
Example: `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"`,
|
||||
Required: false,
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
Title: "Azure AD: Client credentials",
|
||||
Description: "Authenticate using Azure AD with client credentials, also known as \"service principals\".",
|
||||
Metadata: mergedMetadata(bi.Metadata,
|
||||
Metadata{
|
||||
Name: "azureTenantId",
|
||||
Description: "ID of the Azure AD tenant",
|
||||
Example: `"cd4b2887-304c-47e1-b4d5-65447fdd542a"`,
|
||||
Required: true,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureClientId",
|
||||
Description: "Client ID (application ID)",
|
||||
Example: `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"`,
|
||||
Required: true,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureClientSecret",
|
||||
Description: "Client secret (application password)",
|
||||
Example: `"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"`,
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
Title: "Azure AD: Client certificate",
|
||||
Description: `Authenticate using Azure AD with a client certificate. One of "azureCertificate" and "azureCertificateFile" is required.`,
|
||||
Metadata: mergedMetadata(bi.Metadata,
|
||||
Metadata{
|
||||
Name: "azureTenantId",
|
||||
Description: "ID of the Azure AD tenant",
|
||||
Example: `"cd4b2887-304c-47e1-b4d5-65447fdd542a"`,
|
||||
Required: true,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureClientId",
|
||||
Description: "Client ID (application ID)",
|
||||
Example: `"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"`,
|
||||
Required: true,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureCertificate",
|
||||
Description: "Certificate and private key (in either a PEM file containing both the certificate and key, or in PFX/PKCS#12 format)",
|
||||
Example: `"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE----- \n"`,
|
||||
Required: false,
|
||||
Sensitive: true,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureCertificateFile",
|
||||
Description: "Path to PEM or PFX/PKCS#12 file on disk, containing the certificate and private key.",
|
||||
Example: `"/path/to/file.pem"`,
|
||||
Required: false,
|
||||
Sensitive: false,
|
||||
},
|
||||
Metadata{
|
||||
Name: "azureCertificatePassword",
|
||||
Description: "Password for the certificate if encrypted.",
|
||||
Example: `"password"`,
|
||||
Required: false,
|
||||
Sensitive: true,
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
return profiles, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("built-in authentication profile %s does not exist", bi.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func mergedMetadata(base []Metadata, add ...Metadata) []Metadata {
|
||||
if len(base) == 0 {
|
||||
return add
|
||||
}
|
||||
|
||||
res := make([]Metadata, 0, len(base)+len(add))
|
||||
res = append(res, base...)
|
||||
res = append(res, add...)
|
||||
return res
|
||||
}
|
|
@ -41,6 +41,8 @@ type ComponentMetadata struct {
|
|||
Capabilities []string `json:"capabilities,omitempty"`
|
||||
// Authentication profiles for the component.
|
||||
AuthenticationProfiles []AuthenticationProfile `json:"authenticationProfiles,omitempty"`
|
||||
// Built-in authentication profiles to import.
|
||||
BuiltInAuthenticationProfiles []BuiltinAuthenticationProfile `json:"builtinAuthenticationProfiles,omitempty"`
|
||||
// Metadata options for the component.
|
||||
Metadata []Metadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
@ -95,6 +97,8 @@ type Metadata struct {
|
|||
// If set, specifies that the property is only applicable to bindings of the type specified below.
|
||||
// At least one of "input" and "output" must be "true".
|
||||
Binding *MetadataBinding `json:"binding,omitempty"`
|
||||
// URL with additional information, such as docs.
|
||||
URL *URL `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// MetadataBinding is the type for the "binding" property in the "metadata" object.
|
||||
|
@ -114,3 +118,14 @@ type AuthenticationProfile struct {
|
|||
// Metadata options applicable when using this authentication profile.
|
||||
Metadata []Metadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// BuiltinAuthenticationProfile is a reference to a built-in authentication profile.
|
||||
type BuiltinAuthenticationProfile struct {
|
||||
// Name of the built-in authentication profile.
|
||||
// Currently supports:
|
||||
//
|
||||
// - `azuread` (Azure AD, including Managed Identity).
|
||||
Name string `json:"name"`
|
||||
// Additional metadata options applicable when using this authentication profile.
|
||||
Metadata []Metadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
|
|
@ -15,25 +15,33 @@ package metadataschema
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
mdutils "github.com/dapr/components-contrib/metadata"
|
||||
)
|
||||
|
||||
// IsValid performs additional validation and returns true if the object is valid.
|
||||
func (c ComponentMetadata) IsValid() error {
|
||||
// Sanity check for bindings
|
||||
if c.Type == "" {
|
||||
func (c *ComponentMetadata) IsValid() error {
|
||||
// Check valid component type
|
||||
compType := mdutils.ComponentType(c.Type)
|
||||
if c.Type == "" || !compType.IsValid() {
|
||||
return errors.New("type is empty")
|
||||
}
|
||||
if c.Type == "bindings" && c.Binding == nil {
|
||||
return errors.New("property binding is required for components of type 'bindings'")
|
||||
|
||||
// Sanity check for bindings
|
||||
if compType == mdutils.BindingType && c.Binding == nil {
|
||||
return errors.New("property 'binding' is required for components of type 'bindings'")
|
||||
}
|
||||
if c.Type != "bindings" && c.Binding != nil {
|
||||
return errors.New("property binding is not allowed in components that are not of type 'bindings'")
|
||||
if compType != mdutils.BindingType && c.Binding != nil {
|
||||
return errors.New("property 'binding' is not allowed in components that are not of type 'bindings'")
|
||||
}
|
||||
|
||||
// Ensure that there's a URL called Reference to the Dapr docs
|
||||
if len(c.URLs) < 1 {
|
||||
return errors.New("property urls must contain at least one URL to the Dapr docs with title 'Reference'")
|
||||
return errors.New("property 'urls' must contain at least one URL to the Dapr docs with title 'Reference'")
|
||||
}
|
||||
hasReferenceUrl := false
|
||||
for _, u := range c.URLs {
|
||||
|
@ -42,7 +50,111 @@ func (c ComponentMetadata) IsValid() error {
|
|||
}
|
||||
}
|
||||
if !hasReferenceUrl {
|
||||
return errors.New("property urls must a link to the Dapr docs with title 'Reference' and URL starting with 'https://docs.dapr.io/reference/components-reference/'")
|
||||
return errors.New("property 'urls' must a link to the Dapr docs with title 'Reference' and URL starting with 'https://docs.dapr.io/reference/components-reference/'")
|
||||
}
|
||||
|
||||
// Append built-in metadata properties
|
||||
err := c.AppendBuiltin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Append built-in authentication profiles
|
||||
for _, profile := range c.BuiltInAuthenticationProfiles {
|
||||
appendProfiles, err := ParseBuiltinAuthenticationProfile(profile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.AuthenticationProfiles = append(c.AuthenticationProfiles, appendProfiles...)
|
||||
}
|
||||
// Remove the property builtinAuthenticationProfiles now
|
||||
c.BuiltInAuthenticationProfiles = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AppendBuiltin appends built-in metadata properties for the given type.
|
||||
func (c *ComponentMetadata) AppendBuiltin() error {
|
||||
compType := mdutils.ComponentType(c.Type)
|
||||
switch compType {
|
||||
case mdutils.StateStoreType:
|
||||
if c.Metadata == nil {
|
||||
c.Metadata = []Metadata{}
|
||||
}
|
||||
|
||||
if slices.Contains(c.Capabilities, "actorStateStore") {
|
||||
c.Metadata = append(c.Metadata,
|
||||
Metadata{
|
||||
Name: "actorStateStore",
|
||||
Type: "bool",
|
||||
Description: "Use this state store for actors. Defaults to `false`.",
|
||||
Example: `"false"`,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
c.Metadata = append(c.Metadata,
|
||||
Metadata{
|
||||
Name: "keyPrefix",
|
||||
Type: "string",
|
||||
Description: "Prefix added to keys in the state store.",
|
||||
Example: `"appid"`,
|
||||
Default: "appid",
|
||||
URL: &URL{
|
||||
Title: "Documentation",
|
||||
URL: "https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-share-state/",
|
||||
},
|
||||
},
|
||||
)
|
||||
case mdutils.LockStoreType:
|
||||
if c.Metadata == nil {
|
||||
c.Metadata = []Metadata{}
|
||||
}
|
||||
c.Metadata = append(c.Metadata,
|
||||
Metadata{
|
||||
Name: "keyPrefix",
|
||||
Type: "string",
|
||||
Description: "Prefix added to keys in the state store.",
|
||||
Example: `"appid"`,
|
||||
Default: "appid",
|
||||
},
|
||||
)
|
||||
case mdutils.PubSubType:
|
||||
if c.Metadata == nil {
|
||||
c.Metadata = []Metadata{}
|
||||
}
|
||||
c.Metadata = append(c.Metadata,
|
||||
Metadata{
|
||||
Name: "consumerID",
|
||||
Type: "string",
|
||||
Description: "Set the consumer ID to control namespacing. Defaults to the app's ID.",
|
||||
Example: `"{namespace}"`,
|
||||
URL: &URL{
|
||||
Title: "Documentation",
|
||||
URL: "https://docs.dapr.io/developing-applications/building-blocks/pubsub/howto-namespace/",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Sanity check to ensure the data is in sync
|
||||
builtin := compType.BuiltInMetadataProperties()
|
||||
allKeys := make(map[string]struct{}, len(c.Metadata))
|
||||
for _, v := range c.Metadata {
|
||||
allKeys[v.Name] = struct{}{}
|
||||
}
|
||||
for _, k := range builtin {
|
||||
_, ok := allKeys[k]
|
||||
if k == "actorStateStore" {
|
||||
hasCapability := slices.Contains(c.Capabilities, "actorStateStore")
|
||||
if hasCapability && !ok {
|
||||
return errors.New("expected to find built-in property 'actorStateStore'")
|
||||
} else if !hasCapability && ok {
|
||||
return errors.New("found property 'actorStateStore' in component that does not have the 'actorStateStore' capability")
|
||||
}
|
||||
} else if !ok {
|
||||
return fmt.Errorf("expected to find built-in property %s", k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -28,8 +28,8 @@ authenticationProfiles:
|
|||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- title: "Azure AD: Managed identity"
|
||||
description: "Authenticate using Azure AD and a managed identity."
|
||||
builtinAuthenticationProfiles:
|
||||
- name: "azuread"
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
|
||||
|
@ -38,67 +38,6 @@ authenticationProfiles:
|
|||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureClientId
|
||||
required: false
|
||||
description: "Client ID (application ID). Required if the service has multiple identities assigned."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- title: "Azure AD: Client credentials"
|
||||
description: "Authenticate using Azure AD with client credentials, also known as \"service principals\"."
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
|
||||
example: '"namespace.servicebus.windows.net"'
|
||||
required: true
|
||||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant"
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542a"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)"
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureClientSecret
|
||||
sensitive: true
|
||||
required: true
|
||||
description: "Client secret (application password)"
|
||||
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
|
||||
- title: "Azure AD: Client certificate"
|
||||
description: "Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of azureCertificate and azureCertificateFile is required."
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
|
||||
example: '"namespace.servicebus.windows.net"'
|
||||
required: true
|
||||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant."
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureCertificate
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Certificate and private key (in PFX/PKCS#12 format)."
|
||||
example: |
|
||||
"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----"
|
||||
- name: azureCertificateFile
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Path to PFX/PKCS#12 file on disk, containing the certificate and private key."
|
||||
example: "/path/to/file.pem"
|
||||
- name: azureCertificatePassword
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Password for the certificate if encrypted."
|
||||
example: "password"
|
||||
metadata:
|
||||
- name: queueName
|
||||
required: true
|
||||
|
|
|
@ -72,6 +72,27 @@
|
|||
],
|
||||
"description": "BindingOperation represents an operation offered by an output binding."
|
||||
},
|
||||
"BuiltinAuthenticationProfile": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the built-in authentication profile.\nCurrently supports:\n\n- `azuread` (Azure AD, including Managed Identity)."
|
||||
},
|
||||
"metadata": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/Metadata"
|
||||
},
|
||||
"type": "array",
|
||||
"description": "Additional metadata options applicable when using this authentication profile."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"description": "BuiltinAuthenticationProfile is a reference to a built-in authentication profile."
|
||||
},
|
||||
"Metadata": {
|
||||
"properties": {
|
||||
"name": {
|
||||
|
@ -118,6 +139,10 @@
|
|||
"binding": {
|
||||
"$ref": "#/$defs/MetadataBinding",
|
||||
"description": "If set, specifies that the property is only applicable to bindings of the type specified below.\nAt least one of \"input\" and \"output\" must be \"true\"."
|
||||
},
|
||||
"url": {
|
||||
"$ref": "#/$defs/URL",
|
||||
"description": "URL with additional information, such as docs."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -237,6 +262,13 @@
|
|||
"type": "array",
|
||||
"description": "Authentication profiles for the component."
|
||||
},
|
||||
"builtinAuthenticationProfiles": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/BuiltinAuthenticationProfile"
|
||||
},
|
||||
"type": "array",
|
||||
"description": "Built-in authentication profiles to import."
|
||||
},
|
||||
"metadata": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/Metadata"
|
||||
|
|
|
@ -40,9 +40,9 @@ type AzureEventHubsMetadata struct {
|
|||
ResourceGroupName string `json:"resourceGroupName" mapstructure:"resourceGroupName"`
|
||||
|
||||
// Binding only
|
||||
EventHub string `json:"eventHub" mapstructure:"eventHub" only:"binding"`
|
||||
ConsumerGroup string `json:"consumerGroup" mapstructure:"consumerGroup" only:"binding"` // Alias for ConsumerID
|
||||
PartitionID string `json:"partitionID" mapstructure:"partitionID" only:"binding"` // Deprecated
|
||||
EventHub string `json:"eventHub" mapstructure:"eventHub" only:"bindings"`
|
||||
ConsumerGroup string `json:"consumerGroup" mapstructure:"consumerGroup" only:"bindings"` // Alias for ConsumerID
|
||||
PartitionID string `json:"partitionID" mapstructure:"partitionID" only:"bindings"` // Deprecated
|
||||
|
||||
// Internal properties
|
||||
namespaceName string
|
||||
|
|
|
@ -49,7 +49,7 @@ type Metadata struct {
|
|||
NamespaceName string `mapstructure:"namespaceName"` // Only for Azure AD
|
||||
|
||||
/** For bindings only **/
|
||||
QueueName string `mapstructure:"queueName" only:"binding"` // Only queues
|
||||
QueueName string `mapstructure:"queueName" only:"bindings"` // Only queues
|
||||
}
|
||||
|
||||
// Keys.
|
||||
|
|
|
@ -252,18 +252,50 @@ func toTimeDurationArrayHookFunc() mapstructure.DecodeHookFunc {
|
|||
type ComponentType string
|
||||
|
||||
const (
|
||||
BindingType ComponentType = "binding"
|
||||
StateStoreType ComponentType = "statestore"
|
||||
SecretStoreType ComponentType = "secretstore"
|
||||
BindingType ComponentType = "bindings"
|
||||
StateStoreType ComponentType = "state"
|
||||
SecretStoreType ComponentType = "secretstores"
|
||||
PubSubType ComponentType = "pubsub"
|
||||
LockStoreType ComponentType = "lockstore"
|
||||
ConfigurationStoreType ComponentType = "configurationstore"
|
||||
LockStoreType ComponentType = "lock"
|
||||
ConfigurationStoreType ComponentType = "configuration"
|
||||
MiddlewareType ComponentType = "middleware"
|
||||
CryptoType ComponentType = "crypto"
|
||||
NameResolutionType ComponentType = "nameresolution"
|
||||
WorkflowType ComponentType = "workflow"
|
||||
WorkflowType ComponentType = "workflows"
|
||||
)
|
||||
|
||||
// IsValid returns true if the component type is valid.
|
||||
func (t ComponentType) IsValid() bool {
|
||||
switch t {
|
||||
case BindingType, StateStoreType,
|
||||
SecretStoreType, PubSubType,
|
||||
LockStoreType, ConfigurationStoreType,
|
||||
MiddlewareType, CryptoType,
|
||||
NameResolutionType, WorkflowType:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// BuiltInMetadataProperties returns the built-in metadata properties for the given component type.
|
||||
// These are normally parsed by the runtime.
|
||||
func (t ComponentType) BuiltInMetadataProperties() []string {
|
||||
switch t {
|
||||
case StateStoreType:
|
||||
return []string{
|
||||
"actorStateStore",
|
||||
"keyPrefix",
|
||||
}
|
||||
case LockStoreType:
|
||||
return []string{
|
||||
"keyPrefix",
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetMetadataInfoFromStructType converts a struct to a map of field name (or struct tag) to field type.
|
||||
// This is used to generate metadata documentation for components.
|
||||
func GetMetadataInfoFromStructType(t reflect.Type, metadataMap *map[string]string, componentType ComponentType) error {
|
||||
|
@ -315,5 +347,6 @@ func GetMetadataInfoFromStructType(t reflect.Type, metadataMap *map[string]strin
|
|||
}
|
||||
(*metadataMap)[fieldName] = currentField.Type.String()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -246,8 +246,8 @@ func TestMetadataStructToStringMap(t *testing.T) {
|
|||
MyRegularDuration time.Duration
|
||||
SomethingWithCustomName string `mapstructure:"something_with_custom_name"`
|
||||
PubSubOnlyProperty string `mapstructure:"pubsub_only_property" only:"pubsub"`
|
||||
BindingOnlyProperty string `mapstructure:"binding_only_property" only:"binding"`
|
||||
PubSubAndBindingProperty string `mapstructure:"pubsub_and_binding_property" only:"pubsub,binding"`
|
||||
BindingOnlyProperty string `mapstructure:"binding_only_property" only:"bindings"`
|
||||
PubSubAndBindingProperty string `mapstructure:"pubsub_and_binding_property" only:"pubsub,bindings"`
|
||||
MyDurationArray []time.Duration
|
||||
NotExportedByMapStructure string `mapstructure:"-"`
|
||||
notExported string //nolint:structcheck,unused
|
||||
|
|
|
@ -17,28 +17,14 @@ authenticationProfiles:
|
|||
- name: connectionString
|
||||
required: true
|
||||
sensitive: true
|
||||
description: "Shared access policy connection string for the Service Bus. Required unless using Azure AD authentication."
|
||||
description: "Shared access policy connection string for the Service Bus."
|
||||
example: '"Endpoint=sb://{ServiceBusNamespace}.servicebus.windows.net/;SharedAccessKeyName={PolicyName};SharedAccessKey={Key};EntityPath={ServiceBus}"'
|
||||
# If omitted, uses the same values as "<root>.binding"
|
||||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- title: "Azure AD: Managed identity"
|
||||
description: "Authenticate using Azure AD and a managed identity."
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name. Required if using Azure AD authentication."
|
||||
example: '"namespace.servicebus.windows.net"'
|
||||
required: true
|
||||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureClientId
|
||||
required: false
|
||||
description: "Client ID (application ID). Required if the service has multiple identities assigned."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- title: "Azure AD: Client credentials"
|
||||
description: "Authenticate using Azure AD with client credentials, also known as \"service principals\"."
|
||||
builtinAuthenticationProfiles:
|
||||
- name: "azuread"
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
|
||||
|
@ -47,53 +33,6 @@ authenticationProfiles:
|
|||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant"
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)"
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureClientSecret
|
||||
sensitive: true
|
||||
required: true
|
||||
description: "Client secret (application password)"
|
||||
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
|
||||
- title: "Azure AD: Client certificate"
|
||||
description: "Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of azureCertificate and azureCertificateFile is required."
|
||||
metadata:
|
||||
- name: namespaceName
|
||||
description: "Parameter to set the address of the Service Bus namespace, as a fully-qualified domain name."
|
||||
example: '"namespace.servicebus.windows.net"'
|
||||
required: true
|
||||
binding:
|
||||
output: true
|
||||
input: true
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant."
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureCertificate
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Certificate and private key (in PFX/PKCS#12 format)."
|
||||
example: |
|
||||
"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----"
|
||||
- name: azureCertificateFile
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Path to PFX/PKCS#12 file on disk, containing the certificate and private key."
|
||||
example: "/path/to/file.pem"
|
||||
- name: azureCertificatePassword
|
||||
sensitive: true
|
||||
required: false
|
||||
description: "Password for the certificate if encrypted."
|
||||
example: "password"
|
||||
metadata:
|
||||
- name: maxRetriableErrorsPerSec
|
||||
description: "Maximum number of retriable errors that are processed per second. If a message fails to be processed with a retriable error, the component adds a delay before it starts processing another message, to avoid immediately re-processing messages that have failed"
|
||||
|
|
|
@ -13,12 +13,14 @@ capabilities:
|
|||
metadata:
|
||||
- name: redisHost
|
||||
required: true
|
||||
description: Connection-string for the redis host. If \"redisType\" is \"cluster\" it can be multiple hosts separated by commas or just a single host
|
||||
description: |
|
||||
Connection-string for the redis host. If "redisType" is "cluster" it can be multiple hosts separated by commas or just a single host
|
||||
example: '"redis-master.default.svc.cluster.local:6379"'
|
||||
type: string
|
||||
- name: redisPassword
|
||||
required: true
|
||||
description: Password for Redis host. No Default. Can be \"secretKeyRef\" to use a secret reference
|
||||
description: |
|
||||
Password for Redis host. No Default. Can be "secretKeyRef" to use a secret reference
|
||||
example: '"KeFg23!"'
|
||||
type: string
|
||||
- name: redisUsername
|
||||
|
@ -33,37 +35,44 @@ metadata:
|
|||
type: string
|
||||
- name: enableTLS
|
||||
required: false
|
||||
description: If the Redis instance supports TLS with public certificates, can be configured to be enabled or disabled. Defaults to \"false\".
|
||||
description: |
|
||||
If the Redis instance supports TLS with public certificates, can be configured to be enabled or disabled. Defaults to "false".
|
||||
example: "false"
|
||||
type: bool
|
||||
- name: redeliverInterval
|
||||
required: false
|
||||
description: The interval between checking for pending messages to redelivery. Defaults to \"60s\". \"0\" disables redelivery.
|
||||
description: |
|
||||
The interval between checking for pending messages to redelivery. Defaults to "60s". "0" disables redelivery.
|
||||
example: "30s"
|
||||
type: duration
|
||||
- name: processingTimeout
|
||||
required: false
|
||||
description: The amount time a message must be pending before attempting to redeliver it. Defaults to \"15s\". \"0\" disables redelivery.
|
||||
description: |
|
||||
The amount time a message must be pending before attempting to redeliver it. Defaults to "15s". "0" disables redelivery.
|
||||
example: "30s"
|
||||
type: duration
|
||||
- name: queueDepth
|
||||
required: false
|
||||
description: The size of the message queue for processing. Defaults to \"100\".
|
||||
description: |
|
||||
The size of the message queue for processing. Defaults to "100".
|
||||
example: "1000"
|
||||
type: number
|
||||
- name: concurrency
|
||||
required: false
|
||||
description: The number of concurrent workers that are processing messages. Defaults to \"10\".
|
||||
description: |
|
||||
The number of concurrent workers that are processing messages. Defaults to "10".
|
||||
example: "15"
|
||||
type: number
|
||||
- name: redisType
|
||||
required: false
|
||||
description: The type of redis. There are two valid values, one is \"node\" for single node mode, the other is \"cluster\" for redis cluster mode. Defaults to \"node\".
|
||||
description: |
|
||||
The type of redis. There are two valid values, one is "node" for single node mode, the other is "cluster" for redis cluster mode. Defaults to "node".
|
||||
example: "cluster"
|
||||
type: string
|
||||
- name: redisDB
|
||||
required: false
|
||||
description: Database selected after connecting to redis. If \"redisType\" is \"cluster\" this option is ignored. Defaults to \"0\".
|
||||
description: |
|
||||
Database selected after connecting to redis. If "redisType" is "cluster" this option is ignored. Defaults to "0".
|
||||
example: "0"
|
||||
type: number
|
||||
- name: redisMaxRetries
|
||||
|
@ -73,22 +82,26 @@ metadata:
|
|||
type: number
|
||||
- name: redisMinRetryInterval
|
||||
required: false
|
||||
description: Minimum backoff for redis commands between each retry. Default is \"8ms\"; \"-1\" disables backoff.
|
||||
description: |
|
||||
Minimum backoff for redis commands between each retry. Default is "8ms"; "-1" disables backoff.
|
||||
example: "8ms"
|
||||
type: duration
|
||||
- name: redisMaxRetryInterval
|
||||
required: false
|
||||
description: Maximum backoff for redis commands between each retry. Default is \"512ms\";\"-1\" disables backoff.
|
||||
description: |
|
||||
Maximum backoff for redis commands between each retry. Default is "512ms";"-1" disables backoff.
|
||||
example: "5s"
|
||||
type: duration
|
||||
- name: dialTimeout
|
||||
required: false
|
||||
description: Dial timeout for establishing new connections. Defaults to \"5s\".
|
||||
description: |
|
||||
Dial timeout for establishing new connections. Defaults to "5s".
|
||||
example: "5s"
|
||||
type: duration
|
||||
- name: readTimeout
|
||||
required: false
|
||||
description: Timeout for socket reads. If reached, redis commands will fail with a timeout instead of blocking. Defaults to \"3s\", \"-1\" for no timeout.
|
||||
description: |
|
||||
Timeout for socket reads. If reached, redis commands will fail with a timeout instead of blocking. Defaults to "3s", "-1" for no timeout.
|
||||
example: "3s"
|
||||
type: duration
|
||||
- name: writeTimeout
|
||||
|
@ -113,22 +126,26 @@ metadata:
|
|||
type: duration
|
||||
- name: minIdleConns
|
||||
required: false
|
||||
description: Minimum number of idle connections to keep open in order to avoid the performance degradation associated with creating new connections. Defaults to \"0\".
|
||||
description: |
|
||||
Minimum number of idle connections to keep open in order to avoid the performance degradation associated with creating new connections. Defaults to "0".
|
||||
example: "2"
|
||||
type: number
|
||||
- name: idleCheckFrequency
|
||||
required: false
|
||||
description: Frequency of idle checks made by idle connections reaper. Default is \"1m\". \"-1\" disables idle connections reaper.
|
||||
description: |
|
||||
Frequency of idle checks made by idle connections reaper. Default is "1m". "-1" disables idle connections reaper.
|
||||
example: "-1"
|
||||
type: duration
|
||||
- name: idleTimeout
|
||||
required: false
|
||||
description: Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is \"5m\". \"-1\" disables idle timeout check.
|
||||
description: |
|
||||
Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is "5m". "-1" disables idle timeout check.
|
||||
example: "10m"
|
||||
type: duration
|
||||
- name: failover
|
||||
required: false
|
||||
description: Property to enabled failover configuration. Needs sentinalMasterName to be set. Defaults to \"false\"
|
||||
description: |
|
||||
Property to enabled failover configuration. Needs sentinalMasterName to be set. Defaults to "false"
|
||||
example: "false"
|
||||
type: bool
|
||||
- name: sentinelMasterName
|
||||
|
|
|
@ -8,74 +8,8 @@ title: "Azure Key Vault"
|
|||
urls:
|
||||
- title: Reference
|
||||
url: https://docs.dapr.io/reference/components-reference/supported-secret-stores/azure-keyvault/
|
||||
authenticationProfiles:
|
||||
- title: "Azure AD: Managed identity"
|
||||
description: |
|
||||
Authenticate using Azure AD and a managed identity.
|
||||
metadata:
|
||||
- name: azureClientId
|
||||
required: false
|
||||
description: |
|
||||
Client ID (application ID). Required if the service has multiple identities assigned.
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- title: "Azure AD: Client credentials"
|
||||
description: |
|
||||
Authenticate using Azure AD with client credentials, also known as "service principals".
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: |
|
||||
ID of the Azure AD tenant
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: |
|
||||
Client ID (application ID)
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureClientSecret
|
||||
required: true
|
||||
sensitive: true
|
||||
description: |
|
||||
Client secret (application password)
|
||||
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
|
||||
- title: "Azure AD: Client certificate"
|
||||
description: |
|
||||
Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of `azureCertificate` and `azureCertificateFile` is required.
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: |
|
||||
ID of the Azure AD tenant.
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: |
|
||||
Client ID (application ID).
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureCertificate
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Certificate and private key (in PFX/PKCS#12 format).
|
||||
example: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgI...
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICoTC...
|
||||
-----END CERTIFICATE-----
|
||||
- name: azureCertificateFile
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Path to PFX/PKCS#12 file on disk, containing the certificate and private key.
|
||||
example: "/path/to/file.pem"
|
||||
- name: azureCertificatePassword
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Password for the certificate if encrypted.
|
||||
example: "password"
|
||||
builtinAuthenticationProfiles:
|
||||
- name: "azuread"
|
||||
metadata:
|
||||
- name: vaultName
|
||||
required: true
|
||||
|
|
|
@ -27,73 +27,8 @@ authenticationProfiles:
|
|||
description: |
|
||||
The key to authenticate to the Cosmos DB account.
|
||||
example: '"my-secret-key"'
|
||||
- title: "Azure AD: Managed identity"
|
||||
description: |
|
||||
Authenticate using Azure AD and a managed identity.
|
||||
metadata:
|
||||
- name: azureClientId
|
||||
required: false
|
||||
description: |
|
||||
Client ID (application ID). Required if the service has multiple identities assigned.
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- title: "Azure AD: Client credentials"
|
||||
description: |
|
||||
Authenticate using Azure AD with client credentials, also known as "service principals".
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: |
|
||||
ID of the Azure AD tenant
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: |
|
||||
Client ID (application ID)
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureClientSecret
|
||||
required: true
|
||||
sensitive: true
|
||||
description: |
|
||||
Client secret (application password)
|
||||
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
|
||||
- title: "Azure AD: Client certificate"
|
||||
description: |
|
||||
Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of `azureCertificate` and `azureCertificateFile` is required.
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: |
|
||||
ID of the Azure AD tenant.
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: |
|
||||
Client ID (application ID).
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureCertificate
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Certificate and private key (in PFX/PKCS#12 format).
|
||||
example: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgI...
|
||||
-----END PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICoTC...
|
||||
-----END CERTIFICATE-----
|
||||
- name: azureCertificateFile
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Path to PFX/PKCS#12 file on disk, containing the certificate and private key.
|
||||
example: "/path/to/file.pem"
|
||||
- name: azureCertificatePassword
|
||||
required: false
|
||||
sensitive: true
|
||||
description: |
|
||||
Password for the certificate if encrypted.
|
||||
example: "password"
|
||||
builtinAuthenticationProfiles:
|
||||
- name: "azuread"
|
||||
metadata:
|
||||
- name: url
|
||||
required: true
|
||||
|
|
|
@ -20,56 +20,8 @@ authenticationProfiles:
|
|||
sensitive: true
|
||||
description: "The key to authenticate to the Storage Account or Cosmos DB Table API."
|
||||
example: '"my-secret-key"'
|
||||
- title: "Azure AD: Managed identity"
|
||||
description: "Authenticate using Azure AD and a managed identity."
|
||||
metadata:
|
||||
- name: azureClientId
|
||||
required: false
|
||||
description: "Client ID (application ID). Required if the service has multiple identities assigned."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- title: "Azure AD: Client credentials"
|
||||
description: "Authenticate using Azure AD with client credentials, also known as \"service principals\"."
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant"
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)"
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureClientSecret
|
||||
required: true
|
||||
sensitive: true
|
||||
description: "Client secret (application password)"
|
||||
example: '"Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E"'
|
||||
- title: "Azure AD: Client certificate"
|
||||
description: "Authenticate using Azure AD with a client certificate (in PFX/PKCS#12 format). One of azureCertificate and azureCertificateFile is required."
|
||||
metadata:
|
||||
- name: azureTenantId
|
||||
required: true
|
||||
description: "ID of the Azure AD tenant."
|
||||
example: '"cd4b2887-304c-47e1-b4d5-65447fdd542b"'
|
||||
- name: azureClientId
|
||||
required: true
|
||||
description: "Client ID (application ID)."
|
||||
example: '"c7dd251f-811f-4ba2-a905-acd4d3f8f08b"'
|
||||
- name: azureCertificate
|
||||
required: false
|
||||
sensitive: true
|
||||
description: "Certificate and private key (in PFX/PKCS#12 format)."
|
||||
example: |
|
||||
"-----BEGIN PRIVATE KEY-----\n MIIEvgI... \n -----END PRIVATE KEY----- \n -----BEGIN CERTIFICATE----- \n MIICoTC... \n -----END CERTIFICATE-----"
|
||||
- name: azureCertificateFile
|
||||
required: false
|
||||
sensitive: true
|
||||
description: "Path to PFX/PKCS#12 file on disk, containing the certificate and private key."
|
||||
example: "/path/to/file.pem"
|
||||
- name: azureCertificatePassword
|
||||
required: false
|
||||
sensitive: true
|
||||
description: "Password for the certificate if encrypted."
|
||||
example: "password"
|
||||
builtinAuthenticationProfiles:
|
||||
- name: "azuread"
|
||||
metadata:
|
||||
- name: accountName
|
||||
description: "The storage account name."
|
||||
|
|
|
@ -48,8 +48,3 @@ metadata:
|
|||
description: Max idle time before unused connections are automatically closed in the connection pool. By default, there's no value and this is left to the database driver to choose.
|
||||
example: "5m"
|
||||
type: duration
|
||||
- name: actorStateStore
|
||||
required: false
|
||||
description: Consider this state store for actors. Defaults to `false`
|
||||
example: "false"
|
||||
type: bool
|
||||
|
|
|
@ -136,11 +136,6 @@ metadata:
|
|||
description: Amount of time after which the client closes idle connections. Should be less than server's timeout. Default is \"5m\". \"-1\" disables idle timeout check.
|
||||
example: "10m"
|
||||
type: duration
|
||||
- name: actorStateStore
|
||||
required: false
|
||||
description: Consider this state store for actors. Defaults to \"false\".
|
||||
example: "true"
|
||||
type: bool
|
||||
- name: ttlInSeconds
|
||||
required: false
|
||||
description: Allows specifying a default Time-to-live (TTL) in seconds that will be applied to every state store request unless TTL is explicitly defined via the request metadata.
|
||||
|
|
Loading…
Reference in New Issue