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:
Alessandro (Ale) Segala 2023-04-11 17:04:34 -07:00 committed by GitHub
parent 8a4d7b8542
commit 5dad8a867c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 493 additions and 408 deletions

View File

@ -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

View File

@ -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 => ../

View File

@ -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=

View File

@ -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.

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -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.