mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-10-19 22:19:12 +08:00
feat(management): inject auth indexes into v8 api-keys config
- Synthesize and populate live `auth_index` attributes into V8 `api-keys` responses - Strip transient `auth_index` and `auth-index` fields from incoming update payloads and root nodes before persistence - Ensure `auth_index` keys are omitted during V8 config transformations Closes: #6287
This commit is contained in:
@@ -2,10 +2,14 @@ package management
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/router-for-me/CLIProxyAPI/v8/internal/config"
|
||||
"github.com/router-for-me/CLIProxyAPI/v8/internal/watcher/synthesizer"
|
||||
coreauth "github.com/router-for-me/CLIProxyAPI/v8/sdk/cliproxy/auth"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type geminiKeyWithAuthIndex struct {
|
||||
@@ -59,14 +63,8 @@ type openAICompatibilityWithAuthIndex struct {
|
||||
AuthIndex string `json:"auth-index,omitempty"`
|
||||
}
|
||||
|
||||
func (h *Handler) liveAuthIndexByID() map[string]string {
|
||||
func liveAuthIndexFromManager(manager *coreauth.Manager) map[string]string {
|
||||
out := map[string]string{}
|
||||
if h == nil {
|
||||
return out
|
||||
}
|
||||
h.mu.Lock()
|
||||
manager := h.authManager
|
||||
h.mu.Unlock()
|
||||
if manager == nil {
|
||||
return out
|
||||
}
|
||||
@@ -91,6 +89,490 @@ func (h *Handler) liveAuthIndexByID() map[string]string {
|
||||
return out
|
||||
}
|
||||
|
||||
func (h *Handler) liveAuthIndexByID() map[string]string {
|
||||
if h == nil {
|
||||
return map[string]string{}
|
||||
}
|
||||
h.mu.Lock()
|
||||
manager := h.authManager
|
||||
h.mu.Unlock()
|
||||
return liveAuthIndexFromManager(manager)
|
||||
}
|
||||
|
||||
func yamlMapScalar(node *yaml.Node, key string) string {
|
||||
if node == nil || node.Kind != yaml.MappingNode {
|
||||
return ""
|
||||
}
|
||||
for i := 0; i+1 < len(node.Content); i += 2 {
|
||||
if node.Content[i].Value == key {
|
||||
return strings.TrimSpace(node.Content[i+1].Value)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func setMapScalar(mapping *yaml.Node, key, value string) {
|
||||
if mapping == nil || mapping.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
for i := 0; i+1 < len(mapping.Content); i += 2 {
|
||||
if mapping.Content[i].Value == key {
|
||||
mapping.Content[i+1].Value = value
|
||||
mapping.Content[i+1].Tag = "!!str"
|
||||
mapping.Content[i+1].Kind = yaml.ScalarNode
|
||||
return
|
||||
}
|
||||
}
|
||||
mapping.Content = append(mapping.Content,
|
||||
&yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: key},
|
||||
&yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: value},
|
||||
)
|
||||
}
|
||||
|
||||
func deleteMapKey(mapping *yaml.Node, key string) bool {
|
||||
if mapping == nil || mapping.Kind != yaml.MappingNode {
|
||||
return false
|
||||
}
|
||||
for i := 0; i+1 < len(mapping.Content); i += 2 {
|
||||
if mapping.Content[i].Value == key {
|
||||
mapping.Content = append(mapping.Content[:i], mapping.Content[i+2:]...)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func stripAPIKeysAuthIndexesFromGroup(group *yaml.Node) {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
deleteMapKey(group, "auth_index")
|
||||
deleteMapKey(group, "auth-index")
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode != nil && keysNode.Kind == yaml.SequenceNode {
|
||||
for _, keyNode := range keysNode.Content {
|
||||
if keyNode != nil && keyNode.Kind == yaml.MappingNode {
|
||||
deleteMapKey(keyNode, "auth_index")
|
||||
deleteMapKey(keyNode, "auth-index")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stripAPIKeysAuthIndexesFromGroups(groupsNode *yaml.Node) {
|
||||
if groupsNode == nil {
|
||||
return
|
||||
}
|
||||
if groupsNode.Kind == yaml.SequenceNode {
|
||||
for _, group := range groupsNode.Content {
|
||||
stripAPIKeysAuthIndexesFromGroup(group)
|
||||
}
|
||||
} else if groupsNode.Kind == yaml.MappingNode {
|
||||
stripAPIKeysAuthIndexesFromGroup(groupsNode)
|
||||
}
|
||||
}
|
||||
|
||||
func stripAPIKeysAuthIndexesFromProvidersMap(apiKeysNode *yaml.Node) {
|
||||
if apiKeysNode == nil || apiKeysNode.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
for i := 0; i+1 < len(apiKeysNode.Content); i += 2 {
|
||||
stripAPIKeysAuthIndexesFromGroups(apiKeysNode.Content[i+1])
|
||||
}
|
||||
}
|
||||
|
||||
func stripAPIKeysAuthIndexesFromRoot(root *yaml.Node) {
|
||||
if root == nil || root.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
apiKeysNode := configV8Node(root, []string{"api-keys"})
|
||||
if apiKeysNode != nil {
|
||||
stripAPIKeysAuthIndexesFromProvidersMap(apiKeysNode)
|
||||
}
|
||||
}
|
||||
|
||||
func stripAPIKeysAuthIndexesFromUpdate(parts []string, update *yaml.Node) {
|
||||
if update == nil || len(update.Content) == 0 {
|
||||
return
|
||||
}
|
||||
node := update.Content[0]
|
||||
if len(parts) == 0 {
|
||||
stripAPIKeysAuthIndexesFromRoot(node)
|
||||
return
|
||||
}
|
||||
if parts[0] != "api-keys" {
|
||||
return
|
||||
}
|
||||
if len(parts) == 1 {
|
||||
stripAPIKeysAuthIndexesFromProvidersMap(node)
|
||||
return
|
||||
}
|
||||
stripAPIKeysAuthIndexesFromGroups(node)
|
||||
}
|
||||
|
||||
func yamlMapScalarPresent(node *yaml.Node, key string) (string, bool) {
|
||||
if node == nil || node.Kind != yaml.MappingNode {
|
||||
return "", false
|
||||
}
|
||||
for i := 0; i+1 < len(node.Content); i += 2 {
|
||||
if node.Content[i].Value == key {
|
||||
if node.Content[i+1].Tag == "!!null" {
|
||||
return "", false
|
||||
}
|
||||
return strings.TrimSpace(node.Content[i+1].Value), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func yamlMapHeadersPresent(node *yaml.Node, key string) (map[string]string, bool) {
|
||||
if node == nil || node.Kind != yaml.MappingNode {
|
||||
return nil, false
|
||||
}
|
||||
for i := 0; i+1 < len(node.Content); i += 2 {
|
||||
if node.Content[i].Value == key {
|
||||
if node.Content[i+1].Tag == "!!null" {
|
||||
return nil, false
|
||||
}
|
||||
var h map[string]string
|
||||
if errDecode := node.Content[i+1].Decode(&h); errDecode == nil {
|
||||
return h, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func resolveInheritedScalar(keyNode, groupNode *yaml.Node, field string) string {
|
||||
if val, ok := yamlMapScalarPresent(keyNode, field); ok {
|
||||
return val
|
||||
}
|
||||
if val, ok := yamlMapScalarPresent(groupNode, field); ok {
|
||||
return val
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func resolveInheritedHeaders(keyNode, groupNode *yaml.Node, field string) map[string]string {
|
||||
if h, ok := yamlMapHeadersPresent(keyNode, field); ok {
|
||||
return h
|
||||
}
|
||||
if h, ok := yamlMapHeadersPresent(groupNode, field); ok {
|
||||
return h
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeModelPrefixHelper(prefix string) string {
|
||||
trimmed := strings.TrimSpace(prefix)
|
||||
trimmed = strings.Trim(trimmed, "/")
|
||||
if trimmed == "" || strings.Contains(trimmed, "/") {
|
||||
return ""
|
||||
}
|
||||
return trimmed
|
||||
}
|
||||
|
||||
func formatCredentialDedupKey(key, base, proxyURL, prefix string, headers map[string]string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString(strings.TrimSpace(key))
|
||||
b.WriteByte(0)
|
||||
b.WriteString(strings.TrimSpace(base))
|
||||
b.WriteByte(0)
|
||||
b.WriteString(strings.TrimSpace(proxyURL))
|
||||
b.WriteByte(0)
|
||||
b.WriteString(normalizeModelPrefixHelper(prefix))
|
||||
b.WriteByte(0)
|
||||
b.WriteString(config.FormatSortedHeaders(config.NormalizeHeaders(headers)))
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (h *Handler) injectV8APIKeyAuthIndexesLocked(root *yaml.Node, data []byte) {
|
||||
if h == nil || root == nil || root.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
apiKeysNode := configV8Node(root, []string{"api-keys"})
|
||||
if apiKeysNode == nil || apiKeysNode.Kind != yaml.MappingNode {
|
||||
return
|
||||
}
|
||||
|
||||
cfg, errParse := config.ParseConfigBytes(data)
|
||||
if errParse != nil {
|
||||
cfg = h.cfg
|
||||
}
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
synth := synthesizer.NewConfigSynthesizer()
|
||||
synthCtx := &synthesizer.SynthesisContext{
|
||||
Config: cfg,
|
||||
Now: time.Now(),
|
||||
IDGenerator: synthesizer.NewStableIDGenerator(),
|
||||
}
|
||||
auths, errSynth := synth.Synthesize(synthCtx)
|
||||
if errSynth != nil {
|
||||
return
|
||||
}
|
||||
|
||||
liveIndexByID := liveAuthIndexFromManager(h.authManager)
|
||||
resolveAuthIndex := func(a *coreauth.Auth) string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
if idx := strings.TrimSpace(liveIndexByID[a.ID]); idx != "" {
|
||||
return idx
|
||||
}
|
||||
return a.EnsureIndex()
|
||||
}
|
||||
|
||||
authsByProvider := make(map[string][]*coreauth.Auth)
|
||||
for _, a := range auths {
|
||||
if a != nil {
|
||||
authsByProvider[a.Provider] = append(authsByProvider[a.Provider], a)
|
||||
}
|
||||
}
|
||||
|
||||
providerAuthMap := make(map[string]map[string]string)
|
||||
for _, p := range []string{"gemini", "interactions", "vertex"} {
|
||||
providerAuthMap[p] = make(map[string]string)
|
||||
}
|
||||
|
||||
for _, a := range authsByProvider["gemini"] {
|
||||
if a == nil || a.Attributes == nil {
|
||||
continue
|
||||
}
|
||||
idx, errConv := strconv.Atoi(a.Attributes["config_index"])
|
||||
if errConv != nil || idx < 0 || idx >= len(cfg.GeminiKey) {
|
||||
continue
|
||||
}
|
||||
e := cfg.GeminiKey[idx]
|
||||
key := formatCredentialDedupKey(e.APIKey, e.BaseURL, e.ProxyURL, e.Prefix, e.Headers)
|
||||
providerAuthMap["gemini"][key] = resolveAuthIndex(a)
|
||||
}
|
||||
for _, a := range authsByProvider["gemini-interactions"] {
|
||||
if a == nil || a.Attributes == nil {
|
||||
continue
|
||||
}
|
||||
idx, errConv := strconv.Atoi(a.Attributes["config_index"])
|
||||
if errConv != nil || idx < 0 || idx >= len(cfg.InteractionsKey) {
|
||||
continue
|
||||
}
|
||||
e := cfg.InteractionsKey[idx]
|
||||
key := formatCredentialDedupKey(e.APIKey, e.BaseURL, e.ProxyURL, e.Prefix, e.Headers)
|
||||
providerAuthMap["interactions"][key] = resolveAuthIndex(a)
|
||||
}
|
||||
for _, a := range authsByProvider["vertex"] {
|
||||
if a == nil || a.Attributes == nil {
|
||||
continue
|
||||
}
|
||||
idx, errConv := strconv.Atoi(a.Attributes["config_index"])
|
||||
if errConv != nil || idx < 0 || idx >= len(cfg.VertexCompatAPIKey) {
|
||||
continue
|
||||
}
|
||||
e := cfg.VertexCompatAPIKey[idx]
|
||||
key := strings.TrimSpace(e.APIKey) + "|" + strings.TrimSpace(e.BaseURL)
|
||||
providerAuthMap["vertex"][key] = resolveAuthIndex(a)
|
||||
}
|
||||
|
||||
authByConfigIndex := make(map[string]map[string]*coreauth.Auth)
|
||||
for _, p := range []string{"codex", "claude", "xai", "meta"} {
|
||||
authByConfigIndex[p] = make(map[string]*coreauth.Auth)
|
||||
for _, a := range authsByProvider[p] {
|
||||
if a != nil && a.Attributes != nil {
|
||||
authByConfigIndex[p][a.Attributes["config_index"]] = a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i+1 < len(apiKeysNode.Content); i += 2 {
|
||||
providerName := strings.TrimSpace(apiKeysNode.Content[i].Value)
|
||||
groupsNode := apiKeysNode.Content[i+1]
|
||||
if groupsNode == nil || groupsNode.Kind != yaml.SequenceNode {
|
||||
continue
|
||||
}
|
||||
|
||||
if providerName == "openai-compatibility" {
|
||||
validGroupIdx := 0
|
||||
for _, group := range groupsNode.Content {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
groupBase := strings.TrimSpace(yamlMapScalar(group, "base-url"))
|
||||
if groupBase == "" {
|
||||
continue
|
||||
}
|
||||
targetGroupIdxStr := strconv.Itoa(validGroupIdx)
|
||||
validGroupIdx++
|
||||
|
||||
isOpenAICompatAuth := func(a *coreauth.Auth) bool {
|
||||
if a == nil || a.Attributes == nil {
|
||||
return false
|
||||
}
|
||||
if a.Attributes["config_index"] != targetGroupIdxStr {
|
||||
return false
|
||||
}
|
||||
return a.Provider == "openai-compatibility" || strings.HasPrefix(a.Provider, "openai-compatible-")
|
||||
}
|
||||
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode == nil || keysNode.Kind != yaml.SequenceNode || len(keysNode.Content) == 0 {
|
||||
for _, a := range auths {
|
||||
if isOpenAICompatAuth(a) && a.Attributes["api_key"] == "" {
|
||||
if idx := resolveAuthIndex(a); idx != "" {
|
||||
setMapScalar(group, "auth_index", idx)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var groupAuths []*coreauth.Auth
|
||||
for _, a := range auths {
|
||||
if isOpenAICompatAuth(a) {
|
||||
groupAuths = append(groupAuths, a)
|
||||
}
|
||||
}
|
||||
|
||||
for kIdx, keyNode := range keysNode.Content {
|
||||
if keyNode == nil || keyNode.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
if kIdx < len(groupAuths) {
|
||||
if idx := resolveAuthIndex(groupAuths[kIdx]); idx != "" {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if providerName == "claude" {
|
||||
rawIdx := 0
|
||||
for _, group := range groupsNode.Content {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
groupBase := strings.TrimSpace(yamlMapScalar(group, "base-url"))
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode == nil || keysNode.Kind != yaml.SequenceNode {
|
||||
continue
|
||||
}
|
||||
for _, keyNode := range keysNode.Content {
|
||||
if keyNode == nil || keyNode.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
apiKey := strings.TrimSpace(yamlMapScalar(keyNode, "api-key"))
|
||||
targetIdx := strconv.Itoa(rawIdx)
|
||||
rawIdx++
|
||||
if apiKey == "" && groupBase == "" {
|
||||
continue
|
||||
}
|
||||
if a := authByConfigIndex["claude"][targetIdx]; a != nil {
|
||||
if idx := resolveAuthIndex(a); idx != "" {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if providerName == "codex" || providerName == "xai" {
|
||||
validIdx := 0
|
||||
for _, group := range groupsNode.Content {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
groupBase := strings.TrimSpace(yamlMapScalar(group, "base-url"))
|
||||
if groupBase == "" {
|
||||
continue
|
||||
}
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode == nil || keysNode.Kind != yaml.SequenceNode {
|
||||
continue
|
||||
}
|
||||
for _, keyNode := range keysNode.Content {
|
||||
if keyNode == nil || keyNode.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
targetIdx := strconv.Itoa(validIdx)
|
||||
validIdx++
|
||||
if a := authByConfigIndex[providerName][targetIdx]; a != nil {
|
||||
if idx := resolveAuthIndex(a); idx != "" {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if providerName == "meta" {
|
||||
validIdx := 0
|
||||
for _, group := range groupsNode.Content {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode == nil || keysNode.Kind != yaml.SequenceNode {
|
||||
continue
|
||||
}
|
||||
for _, keyNode := range keysNode.Content {
|
||||
if keyNode == nil || keyNode.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
apiKey := strings.TrimSpace(yamlMapScalar(keyNode, "api-key"))
|
||||
if apiKey == "" || strings.HasPrefix(apiKey, "dca:") {
|
||||
continue
|
||||
}
|
||||
targetIdx := strconv.Itoa(validIdx)
|
||||
validIdx++
|
||||
if a := authByConfigIndex["meta"][targetIdx]; a != nil {
|
||||
if idx := resolveAuthIndex(a); idx != "" {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
for _, group := range groupsNode.Content {
|
||||
if group == nil || group.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
groupBase := strings.TrimSpace(yamlMapScalar(group, "base-url"))
|
||||
keysNode := configV8Node(group, []string{"keys"})
|
||||
if keysNode == nil || keysNode.Kind != yaml.SequenceNode {
|
||||
continue
|
||||
}
|
||||
for _, keyNode := range keysNode.Content {
|
||||
if keyNode == nil || keyNode.Kind != yaml.MappingNode {
|
||||
continue
|
||||
}
|
||||
apiKey := strings.TrimSpace(yamlMapScalar(keyNode, "api-key"))
|
||||
if providerName == "vertex" {
|
||||
if idx, ok := providerAuthMap["vertex"][apiKey+"|"+groupBase]; ok {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
proxyURL := resolveInheritedScalar(keyNode, group, "proxy-url")
|
||||
prefix := resolveInheritedScalar(keyNode, group, "prefix")
|
||||
headers := resolveInheritedHeaders(keyNode, group, "headers")
|
||||
dedupKey := formatCredentialDedupKey(apiKey, groupBase, proxyURL, prefix, headers)
|
||||
if idx, ok := providerAuthMap[providerName][dedupKey]; ok {
|
||||
setMapScalar(keyNode, "auth_index", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) geminiKeysWithAuthIndex() []geminiKeyWithAuthIndex {
|
||||
if h == nil {
|
||||
return nil
|
||||
|
||||
@@ -52,6 +52,7 @@ func (h *Handler) ConfigV8(c *gin.Context) {
|
||||
deleteConfigV8Path(server, []string{"credential"})
|
||||
}
|
||||
}
|
||||
h.injectV8APIKeyAuthIndexesLocked(root, data)
|
||||
}
|
||||
value := configV8Node(root, parts)
|
||||
if value == nil {
|
||||
@@ -97,6 +98,7 @@ func (h *Handler) ConfigV8(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_body"})
|
||||
return
|
||||
}
|
||||
stripAPIKeysAuthIndexesFromUpdate(parts, &update)
|
||||
if len(parts) == 0 && update.Content[0].Kind != yaml.MappingNode {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "config_must_be_object"})
|
||||
return
|
||||
@@ -155,6 +157,7 @@ func (h *Handler) ConfigV8(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
stripAPIKeysAuthIndexesFromRoot(root)
|
||||
data, err = yaml.Marshal(&doc)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_config", "message": err.Error()})
|
||||
|
||||
1280
internal/api/handlers/management/config_v8_auth_index_test.go
Normal file
1280
internal/api/handlers/management/config_v8_auth_index_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -371,7 +371,14 @@ func expandV8Groups(groups *yaml.Node, provider string) (*yaml.Node, error) {
|
||||
if provider == "openai-compatibility" {
|
||||
item := deepCopyNode(group)
|
||||
deleteYAMLPath(item, "keys")
|
||||
setYAMLPath(item, "api-key-entries", keys)
|
||||
deleteYAMLPath(item, "auth_index")
|
||||
deleteYAMLPath(item, "auth-index")
|
||||
cleanKeys := deepCopyNode(keys)
|
||||
for _, k := range cleanKeys.Content {
|
||||
deleteYAMLPath(k, "auth_index")
|
||||
deleteYAMLPath(k, "auth-index")
|
||||
}
|
||||
setYAMLPath(item, "api-key-entries", cleanKeys)
|
||||
out.Content = append(out.Content, item)
|
||||
continue
|
||||
}
|
||||
@@ -396,6 +403,9 @@ func expandV8Groups(groups *yaml.Node, provider string) (*yaml.Node, error) {
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(key.Content); i += 2 {
|
||||
if key.Content[i].Value == "auth_index" || key.Content[i].Value == "auth-index" {
|
||||
continue
|
||||
}
|
||||
if key.Content[i+1].Tag != "!!null" {
|
||||
setYAMLPath(item, key.Content[i].Value, key.Content[i+1])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user