1DBIx::Class::Schema::CoUnsfeirg(C3o)ntributed Perl DocumDeBnItxa:t:iColnass::Schema::Config(3)
2
3
4
6 DBIx::Class::Schema::Config - Credential Management for DBIx::Class
7
9 DBIx::Class::Schema::Config is a subclass of DBIx::Class::Schema that
10 allows the loading of credentials & configuration from a file. The
11 actual code itself would only need to know about the name used in the
12 configuration file. This aims to make it simpler for operations teams
13 to manage database credentials.
14
15 A simple tutorial that compliments this documentation and explains
16 converting an existing DBIx::Class Schema to use this software to
17 manage credentials can be found at
18 <http://www.symkat.com/credential-management-in-dbix-class>
19
21 /etc/dbic.yaml
22 MY_DATABASE:
23 dsn: "dbi:Pg:host=localhost;database=blog"
24 user: "TheDoctor"
25 password: "dnoPydoleM"
26 TraceLevel: 1
27
28 package My::Schema
29 use warnings;
30 use strict;
31
32 use base 'DBIx::Class::Schema::Config';
33 __PACKAGE__->load_namespaces;
34
35 package My::Code;
36 use warnings;
37 use strict;
38 use My::Schema;
39
40 my $schema = My::Schema->connect('MY_DATABASE');
41
42 # arbitrary config access from anywhere in your $app
43 my $level = My::Schema->config->{TraceLevel};
44
46 This module will load the files in the following order if they exist:
47
48 • $ENV{DBIX_CONFIG_DIR} . '/dbic',
49
50 $ENV{DBIX_CONFIG_DIR} can be configured at run-time, for instance:
51
52 DBIX_CONFIG_DIR="/var/local/" ./my_program.pl
53
54 • ./dbic.*
55
56 • ~/.dbic.*
57
58 • /etc/dbic.*
59
60 The files should have an extension that Config::Any recognizes, for
61 example /etc/dbic.yaml.
62
63 NOTE: The first available credential will be used. Therefore DATABASE
64 in ~/.dbic.yaml will only be looked at if it was not found in
65 ./dbic.yaml. If there are duplicates in one file (such that DATABASE
66 is listed twice in ~/.dbic.yaml,) the first configuration will be used.
67
69 Use "__PACKAGE__->config_paths([( '/file/stub',
70 '/var/www/etc/dbic')]);" to change the paths that are searched. For
71 example:
72
73 package My::Schema
74 use warnings;
75 use strict;
76
77 use base 'DBIx::Class::Schema::Config';
78 __PACKAGE__->config_paths([( '/var/www/secret/dbic', '/opt/database' )]);
79
80 The above code would have /var/www/secret/dbic.* and /opt/database.*
81 searched, in that order. As above, the first credentials found would
82 be used. This will replace the files originally searched for, not add
83 to them.
84
86 If you would rather explicitly state the configuration files you want
87 loaded, you can use the class accessor "config_files" instead.
88
89 package My::Schema
90 use warnings;
91 use strict;
92
93 use base 'DBIx::Class::Schema::Config';
94 __PACKAGE__->config_files([( '/var/www/secret/dbic.yaml', '/opt/database.yaml' )]);
95
96 This will check the files, "/var/www/secret/dbic.yaml", and
97 "/opt/database.yaml" in the same way as "config_paths", however it will
98 only check the specific files, instead of checking for each extension
99 that Config::Any supports. You MUST use the extension that corresponds
100 to the file type you are loading. See Config::Any for information on
101 supported file types and extension mapping.
102
104 The config file is stored via the "__PACKAGE__->config" accessor,
105 which can be called as both a class and instance method.
106
108 The API has been designed to be simple to override if you have
109 additional needs in loading DBIC configurations.
110
111 Mojo::Pg-Like Connection Strings
112 Calls to connect with Mojo::Pg-like URIs are supported.
113
114 my $schema = My::Schema->connect( 'postgresql://username:password@localhost/dbname' );
115
116 Overriding Connection Configuration
117 Simple cases where one wants to replace specific configuration tokens
118 can be given as extra parameters in the ->connect call.
119
120 For example, suppose we have the database MY_DATABASE from above:
121
122 MY_DATABASE:
123 dsn: "dbi:Pg:host=localhost;database=blog"
124 user: "TheDoctor"
125 password: "dnoPydoleM"
126 TraceLevel: 1
127
128 If you’d like to replace the username with “Eccleston” and we’d like to
129 turn PrintError off.
130
131 The following connect line would achieve this:
132
133 $Schema->connect(“MY_DATABASE”, “Eccleston”, undef, { PrintError => 0 } );
134
135 The name of the connection to load from the configuration file is still
136 given as the first argument, while other arguments may be given exactly
137 as you would for any other call to "connect".
138
139 Historical Note: This class accepts numerous ways to connect to DBIC
140 that would otherwise not be valid. These connection methods are
141 discouraged but tested for and kept for compatibility with earlier
142 versions. For valid ways of connecting to DBIC please see
143 <https://metacpan.org/pod/DBIx::Class::Storage::DBI#connect_info>
144
145 filter_loaded_credentials
146 Override this function if you want to change the loaded credentials
147 before they are passed to DBIC. This is useful for use-cases that
148 include decrypting encrypted passwords or making programmatic changes
149 to the configuration before using it.
150
151 sub filter_loaded_credentials {
152 my ( $class, $loaded_credentials, $connect_args ) = @_;
153 ...
154 return $loaded_credentials;
155 }
156
157 $loaded_credentials is the structure after it has been loaded from the
158 configuration file. In this case, "$loaded_credentials->{user}" eq
159 WalterWhite and "$loaded_credentials->{dsn}" eq
160 DBI:mysql:database=students;host=%s;port=3306.
161
162 $connect_args is the structure originally passed on "->connect()" after
163 it has been turned into a hash. For instance, "->connect('DATABASE',
164 'USERNAME')" will result in "$connect_args->{dsn}" eq DATABASE and
165 "$connect_args->{user}" eq USERNAME.
166
167 Additional parameters can be added by appending a hashref, to the
168 connection call, as an example, "->connect( 'CONFIG', { hostname =>
169 "db.foo.com" } );" will give $connect_args a structure like "{ dsn =>
170 'CONFIG', hostname => "db.foo.com" }".
171
172 For instance, if you want to use hostnames when you make the initial
173 connection to DBIC and are using the configuration primarily for
174 usernames, passwords and other configuration data, you can create a
175 config like the following:
176
177 DATABASE:
178 dsn: "DBI:mysql:database=students;host=%s;port=3306"
179 user: "WalterWhite"
180 password: "relykS"
181
182 In your Schema class, you could include the following:
183
184 package My::Schema
185 use warnings;
186 use strict;
187 use base 'DBIx::Class::Schema::Config';
188
189 sub filter_loaded_credentials {
190 my ( $class, $loaded_credentials, $connect_args ) = @_;
191 if ( $loaded_credentials->{dsn} =~ /\%s/ ) {
192 $loaded_credentials->{dsn} = sprintf( $loaded_credentials->{dsn},
193 $connect_args->{hostname});
194 }
195 }
196
197 __PACKAGE__->load_classes;
198 1;
199
200 Then the connection could be done with "$Schema->connect('DATABASE', {
201 hostname =" 'my.hostname.com' });>
202
203 See "load_credentials" for more complex changes that require changing
204 how the configuration itself is loaded.
205
206 load_credentials
207 Override this function to change the way that
208 DBIx::Class::Schema::Config loads credentials. The function takes the
209 class name, as well as a hashref.
210
211 If you take the route of having "->connect('DATABASE')" used as a key
212 for whatever configuration you are loading, DATABASE would be
213 "$config->{dsn}"
214
215 Some::Schema->connect(
216 "SomeTarget",
217 "Yuri",
218 "Yawny",
219 {
220 TraceLevel => 1
221 }
222 );
223
224 Would result in the following data structure as $config in
225 "load_credentials($class, $config)":
226
227 {
228 dsn => "SomeTarget",
229 user => "Yuri",
230 password => "Yawny",
231 TraceLevel => 1,
232 }
233
234 Currently, load_credentials will NOT be called if the first argument to
235 "->connect()" looks like a valid DSN. This is determined by match the
236 DSN with "/^dbi:/i".
237
238 The function should return the same structure. For instance:
239
240 package My::Schema
241 use warnings;
242 use strict;
243 use base 'DBIx::Class::Schema::Config';
244 use LWP::Simple;
245 use JSON
246
247 # Load credentials from internal web server.
248 sub load_credentials {
249 my ( $class, $config ) = @_;
250
251 return decode_json(
252 get( "http://someserver.com/v1.0/database?key=somesecret&db=" .
253 $config->{dsn} ));
254 }
255
256 __PACKAGE__->load_classes;
257
259 Kaitlyn Parkhurst (SymKat) <symkat@symkat.com> ( Blog:
260 <http://symkat.com/> )
261
263 • Matt S. Trout (mst) <mst@shadowcat.co.uk>
264
265 • Peter Rabbitson (ribasushi) <ribasushi@cpan.org>
266
267 • Christian Walde (Mihtaldu) <walde.christian@googlemail.com>
268
269 • Dagfinn Ilmari Mannsåker (ilmari) <ilmari@ilmari.org>
270
271 • Matthew Phillips (mattp) <mattp@cpan.org>
272
274 This library is free software and may be distributed under the same
275 terms as perl itself.
276
278 The latest version of this software is available at
279 <https://github.com/symkat/DBIx-Class-Schema-Config>
280
281
282
283perl v5.38.0 2023-07-20 DBIx::Class::Schema::Config(3)