1package builtinplugins
2
3import (
4	"github.com/hashicorp/vault/sdk/database/helper/credsutil"
5	"github.com/hashicorp/vault/sdk/helper/consts"
6	"github.com/hashicorp/vault/sdk/logical"
7
8	credAliCloud "github.com/hashicorp/vault-plugin-auth-alicloud"
9	credAzure "github.com/hashicorp/vault-plugin-auth-azure"
10	credCentrify "github.com/hashicorp/vault-plugin-auth-centrify"
11	credGcp "github.com/hashicorp/vault-plugin-auth-gcp/plugin"
12	credJWT "github.com/hashicorp/vault-plugin-auth-jwt"
13	credKube "github.com/hashicorp/vault-plugin-auth-kubernetes"
14	credPCF "github.com/hashicorp/vault-plugin-auth-pcf"
15	credAppId "github.com/hashicorp/vault/builtin/credential/app-id"
16	credAppRole "github.com/hashicorp/vault/builtin/credential/approle"
17	credAws "github.com/hashicorp/vault/builtin/credential/aws"
18	credCert "github.com/hashicorp/vault/builtin/credential/cert"
19	credGitHub "github.com/hashicorp/vault/builtin/credential/github"
20	credLdap "github.com/hashicorp/vault/builtin/credential/ldap"
21	credOkta "github.com/hashicorp/vault/builtin/credential/okta"
22	credRadius "github.com/hashicorp/vault/builtin/credential/radius"
23	credUserpass "github.com/hashicorp/vault/builtin/credential/userpass"
24
25	dbElastic "github.com/hashicorp/vault-plugin-database-elasticsearch"
26	dbCass "github.com/hashicorp/vault/plugins/database/cassandra"
27	dbHana "github.com/hashicorp/vault/plugins/database/hana"
28	dbInflux "github.com/hashicorp/vault/plugins/database/influxdb"
29	dbMongo "github.com/hashicorp/vault/plugins/database/mongodb"
30	dbMssql "github.com/hashicorp/vault/plugins/database/mssql"
31	dbMysql "github.com/hashicorp/vault/plugins/database/mysql"
32	dbPostgres "github.com/hashicorp/vault/plugins/database/postgresql"
33
34	logicalAd "github.com/hashicorp/vault-plugin-secrets-ad/plugin"
35	logicalAlicloud "github.com/hashicorp/vault-plugin-secrets-alicloud"
36	logicalAzure "github.com/hashicorp/vault-plugin-secrets-azure"
37	logicalGcp "github.com/hashicorp/vault-plugin-secrets-gcp/plugin"
38	logicalGcpKms "github.com/hashicorp/vault-plugin-secrets-gcpkms"
39	logicalKv "github.com/hashicorp/vault-plugin-secrets-kv"
40	logicalAws "github.com/hashicorp/vault/builtin/logical/aws"
41	logicalCass "github.com/hashicorp/vault/builtin/logical/cassandra"
42	logicalConsul "github.com/hashicorp/vault/builtin/logical/consul"
43	logicalMongo "github.com/hashicorp/vault/builtin/logical/mongodb"
44	logicalMssql "github.com/hashicorp/vault/builtin/logical/mssql"
45	logicalMysql "github.com/hashicorp/vault/builtin/logical/mysql"
46	logicalNomad "github.com/hashicorp/vault/builtin/logical/nomad"
47	logicalPki "github.com/hashicorp/vault/builtin/logical/pki"
48	logicalPostgres "github.com/hashicorp/vault/builtin/logical/postgresql"
49	logicalRabbit "github.com/hashicorp/vault/builtin/logical/rabbitmq"
50	logicalSsh "github.com/hashicorp/vault/builtin/logical/ssh"
51	logicalTotp "github.com/hashicorp/vault/builtin/logical/totp"
52	logicalTransit "github.com/hashicorp/vault/builtin/logical/transit"
53)
54
55// Registry is inherently thread-safe because it's immutable.
56// Thus, rather than creating multiple instances of it, we only need one.
57var Registry = newRegistry()
58
59var addExternalPlugins = addExtPluginsImpl
60
61// BuiltinFactory is the func signature that should be returned by
62// the plugin's New() func.
63type BuiltinFactory func() (interface{}, error)
64
65func newRegistry() *registry {
66	reg := &registry{
67		credentialBackends: map[string]logical.Factory{
68			"alicloud":   credAliCloud.Factory,
69			"app-id":     credAppId.Factory,
70			"approle":    credAppRole.Factory,
71			"aws":        credAws.Factory,
72			"azure":      credAzure.Factory,
73			"centrify":   credCentrify.Factory,
74			"cert":       credCert.Factory,
75			"gcp":        credGcp.Factory,
76			"github":     credGitHub.Factory,
77			"jwt":        credJWT.Factory,
78			"kubernetes": credKube.Factory,
79			"ldap":       credLdap.Factory,
80			"oidc":       credJWT.Factory,
81			"okta":       credOkta.Factory,
82			"pcf":        credPCF.Factory,
83			"radius":     credRadius.Factory,
84			"userpass":   credUserpass.Factory,
85		},
86		databasePlugins: map[string]BuiltinFactory{
87			// These four plugins all use the same mysql implementation but with
88			// different username settings passed by the constructor.
89			"mysql-database-plugin":        dbMysql.New(dbMysql.MetadataLen, dbMysql.MetadataLen, dbMysql.UsernameLen),
90			"mysql-aurora-database-plugin": dbMysql.New(credsutil.NoneLength, dbMysql.LegacyMetadataLen, dbMysql.LegacyUsernameLen),
91			"mysql-rds-database-plugin":    dbMysql.New(credsutil.NoneLength, dbMysql.LegacyMetadataLen, dbMysql.LegacyUsernameLen),
92			"mysql-legacy-database-plugin": dbMysql.New(credsutil.NoneLength, dbMysql.LegacyMetadataLen, dbMysql.LegacyUsernameLen),
93
94			"postgresql-database-plugin":    dbPostgres.New,
95			"mssql-database-plugin":         dbMssql.New,
96			"cassandra-database-plugin":     dbCass.New,
97			"mongodb-database-plugin":       dbMongo.New,
98			"hana-database-plugin":          dbHana.New,
99			"influxdb-database-plugin":      dbInflux.New,
100			"elasticsearch-database-plugin": dbElastic.New,
101		},
102		logicalBackends: map[string]logical.Factory{
103			"ad":         logicalAd.Factory,
104			"alicloud":   logicalAlicloud.Factory,
105			"aws":        logicalAws.Factory,
106			"azure":      logicalAzure.Factory,
107			"cassandra":  logicalCass.Factory,
108			"consul":     logicalConsul.Factory,
109			"gcp":        logicalGcp.Factory,
110			"gcpkms":     logicalGcpKms.Factory,
111			"kv":         logicalKv.Factory,
112			"mongodb":    logicalMongo.Factory,
113			"mssql":      logicalMssql.Factory,
114			"mysql":      logicalMysql.Factory,
115			"nomad":      logicalNomad.Factory,
116			"pki":        logicalPki.Factory,
117			"postgresql": logicalPostgres.Factory,
118			"rabbitmq":   logicalRabbit.Factory,
119			"ssh":        logicalSsh.Factory,
120			"totp":       logicalTotp.Factory,
121			"transit":    logicalTransit.Factory,
122		},
123	}
124
125	addExternalPlugins(reg)
126
127	return reg
128}
129
130func addExtPluginsImpl(r *registry) {}
131
132type registry struct {
133	credentialBackends map[string]logical.Factory
134	databasePlugins    map[string]BuiltinFactory
135	logicalBackends    map[string]logical.Factory
136}
137
138// Get returns the BuiltinFactory func for a particular backend plugin
139// from the plugins map.
140func (r *registry) Get(name string, pluginType consts.PluginType) (func() (interface{}, error), bool) {
141	switch pluginType {
142	case consts.PluginTypeCredential:
143		f, ok := r.credentialBackends[name]
144		return toFunc(f), ok
145	case consts.PluginTypeSecrets:
146		f, ok := r.logicalBackends[name]
147		return toFunc(f), ok
148	case consts.PluginTypeDatabase:
149		f, ok := r.databasePlugins[name]
150		return f, ok
151	default:
152		return nil, false
153	}
154}
155
156// Keys returns the list of plugin names that are considered builtin plugins.
157func (r *registry) Keys(pluginType consts.PluginType) []string {
158	var keys []string
159	switch pluginType {
160	case consts.PluginTypeDatabase:
161		for key := range r.databasePlugins {
162			keys = append(keys, key)
163		}
164	case consts.PluginTypeCredential:
165		for key := range r.credentialBackends {
166			keys = append(keys, key)
167		}
168	case consts.PluginTypeSecrets:
169		for key := range r.logicalBackends {
170			keys = append(keys, key)
171		}
172	}
173	return keys
174}
175
176func (r *registry) Contains(name string, pluginType consts.PluginType) bool {
177	for _, key := range r.Keys(pluginType) {
178		if key == name {
179			return true
180		}
181	}
182	return false
183}
184
185func toFunc(ifc interface{}) func() (interface{}, error) {
186	return func() (interface{}, error) {
187		return ifc, nil
188	}
189}
190