func (a Authorization) ValidateAuthorizedAdmin(adminSecret string) func() error {
	return func() error {
		if a.Key != "admin" {
			return fmt.Errorf("must be an authorized admin")
		}
		if a.Secret != adminSecret {
			return fmt.Errorf("must be an authorized admin, invalid admin secret")
		}
		return nil
	}
}
ValidateAuthorizedAdmin determines if the Authorization is valid and an admin.
TODO See if this can be removed when refactoring auth.
Optional validation should be passed as parameter to Validate().
package credentials
import (
	"errors"
	"fmt"
	"net/http"
	"strings"
	"github.com/argoproj-labs/argo-cloudops/internal/requests"
	"github.com/argoproj-labs/argo-cloudops/internal/responses"
	"github.com/argoproj-labs/argo-cloudops/internal/validations"
	"github.com/argoproj-labs/argo-cloudops/service/internal/env"
	vault "github.com/hashicorp/vault/api"
)
const (
	authorizationKeyAdmin = "admin"
)
type Provider interface {
	CreateProject(string) (string, string, error)
	CreateTarget(string, requests.CreateTarget) error
	DeleteProject(string) error
	DeleteTarget(string, string) error
	GetProject(string) (responses.GetProject, error)
	GetTarget(string, string) (responses.TargetProperties, error)
	GetToken() (string, error)
	ListTargets(string) ([]string, error)
	ProjectExists(string) (bool, error)
	TargetExists(string, string) (bool, error)
}
type vaultLogical interface {
	Delete(path string) (*vault.Secret, error)
	List(path string) (*vault.Secret, error)
	Read(path string) (*vault.Secret, error)
	Write(path string, data map[string]interface{}) (*vault.Secret, error)
}
type vaultSys interface {
	DeletePolicy(name string) error
	PutPolicy(name, rules string) error
}
const (
	vaultAppRolePrefix = "auth/approle/role"
	vaultProjectPrefix = "argo-cloudops-projects"
)
var (
	ErrNotFound = errors.New("item not found")
	ErrTargetNotFound = errors.New("target not found")
)
type VaultProvider struct {
	roleID          string
	secretID        string
	vaultLogicalSvc vaultLogical
	vaultSysSvc     vaultSys
}
func NewVaultProvider(a Authorization, env env.Vars, h http.Header, vaultConfigFn VaultConfigFn, vaultSvcFn VaultSvcFn) (Provider, error) {
	config := vaultConfigFn(&vault.Config{Address: env.VaultAddress}, env.VaultRole, env.VaultSecret)
	svc, err := vaultSvcFn(*config, h)
	if err != nil {
		return nil, err
	}
	return &VaultProvider{
		vaultLogicalSvc: vaultLogical(svc.Logical()),
		vaultSysSvc:     vaultSys(svc.Sys()),
		roleID:          a.Key,
		secretID:        a.Secret,
	}, nil
}
type VaultConfig struct {
	config *vault.Config
	role   string
	secret string
}
type VaultConfigFn func(config *vault.Config, role, secret string) *VaultConfig
func NewVaultConfig(config *vault.Config, role, secret string) *VaultConfig {
	return &VaultConfig{
		config: config,
		role:   role,
		secret: secret,
	}
}
type VaultSvcFn func(c VaultConfig, h http.Header) (svc *vault.Client, err error)
func NewVaultSvc(c VaultConfig, h http.Header) (*vault.Client, error) {
	vaultSvc, err := vault.NewClient(c.config)
	if err != nil {
		return nil, err
	}
	vaultSvc.SetHeaders(h)
	options := map[string]interface{}{
		"role_id":   c.role,
		"secret_id": c.secret,
	}
	sec, err := vaultSvc.Logical().Write("auth/approle/login", options)
	if err != nil {
		return nil, err
	}
	vaultSvc.SetToken(sec.Auth.ClientToken)
	return vaultSvc, nil
}
type Authorization struct {
	Provider string `valid:"required"`
	Key      string `valid:"required"`
	Secret   string `valid:"required"`
}
func (a Authorization) Validate(optionalValidations ...func() error) error {
	v := []func() error{
		func() error {
			if a.Provider != "vault" {
				return errors.New("provider must be vault")
			}
			return nil
		},
		func() error { return validations.ValidateStruct(a) },
	}
	v = append(v, optionalValidations...)
	return validations.Validate(v...)
}