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 Overriding Connection Configuration
112 Simple cases where one wants to replace specific configuration tokens
113 can be given as extra parameters in the ->connect call.
114
115 For example, suppose we have the database MY_DATABASE from above:
116
117 MY_DATABASE:
118 dsn: "dbi:Pg:host=localhost;database=blog"
119 user: "TheDoctor"
120 password: "dnoPydoleM"
121 TraceLevel: 1
122
123 If you’d like to replace the username with “Eccleston” and we’d like to
124 turn PrintError off.
125
126 The following connect line would achieve this:
127
128 $Schema->connect(“MY_DATABASE”, “Eccleston”, undef, { PrintError => 0 } );
129
130 The name of the connection to load from the configuration file is still
131 given as the first argument, while other arguments may be given exactly
132 as you would for any other call to "connect".
133
134 Historical Note: This class accepts numerous ways to connect to DBIC
135 that would otherwise not be valid. These connection methods are
136 discouraged but tested for and kept for compatibility with earlier
137 versions. For valid ways of connecting to DBIC please see
138 <https://metacpan.org/pod/DBIx::Class::Storage::DBI#connect_info>
139
140 filter_loaded_credentials
141 Override this function if you want to change the loaded credentials
142 before they are passed to DBIC. This is useful for use-cases that
143 include decrypting encrypted passwords or making programmatic changes
144 to the configuration before using it.
145
146 sub filter_loaded_credentials {
147 my ( $class, $loaded_credentials, $connect_args ) = @_;
148 ...
149 return $loaded_credentials;
150 }
151
152 $loaded_credentials is the structure after it has been loaded from the
153 configuration file. In this case, "$loaded_credentials->{user}" eq
154 WalterWhite and "$loaded_credentials->{dsn}" eq
155 DBI:mysql:database=students;host=%s;port=3306.
156
157 $connect_args is the structure originally passed on "->connect()" after
158 it has been turned into a hash. For instance, "->connect('DATABASE',
159 'USERNAME')" will result in "$connect_args->{dsn}" eq DATABASE and
160 "$connect_args->{user}" eq USERNAME.
161
162 Additional parameters can be added by appending a hashref, to the
163 connection call, as an example, "->connect( 'CONFIG', { hostname =>
164 "db.foo.com" } );" will give $connect_args a structure like "{ dsn =>
165 'CONFIG', hostname => "db.foo.com" }".
166
167 For instance, if you want to use hostnames when you make the initial
168 connection to DBIC and are using the configuration primarily for
169 usernames, passwords and other configuration data, you can create a
170 config like the following:
171
172 DATABASE:
173 dsn: "DBI:mysql:database=students;host=%s;port=3306"
174 user: "WalterWhite"
175 password: "relykS"
176
177 In your Schema class, you could include the following:
178
179 package My::Schema
180 use warnings;
181 use strict;
182 use base 'DBIx::Class::Schema::Config';
183
184 sub filter_loaded_credentials {
185 my ( $class, $loaded_credentials, $connect_args ) = @_;
186 if ( $loaded_credentials->{dsn} =~ /\%s/ ) {
187 $loaded_credentials->{dsn} = sprintf( $loaded_credentials->{dsn},
188 $connect_args->{hostname});
189 }
190 }
191
192 __PACKAGE__->load_classes;
193 1;
194
195 Then the connection could be done with "$Schema->connect('DATABASE', {
196 hostname =" 'my.hostname.com' });>
197
198 See "load_credentials" for more complex changes that require changing
199 how the configuration itself is loaded.
200
201 load_credentials
202 Override this function to change the way that
203 DBIx::Class::Schema::Config loads credentials. The function takes the
204 class name, as well as a hashref.
205
206 If you take the route of having "->connect('DATABASE')" used as a key
207 for whatever configuration you are loading, DATABASE would be
208 "$config->{dsn}"
209
210 Some::Schema->connect(
211 "SomeTarget",
212 "Yuri",
213 "Yawny",
214 {
215 TraceLevel => 1
216 }
217 );
218
219 Would result in the following data structure as $config in
220 "load_credentials($class, $config)":
221
222 {
223 dsn => "SomeTarget",
224 user => "Yuri",
225 password => "Yawny",
226 TraceLevel => 1,
227 }
228
229 Currently, load_credentials will NOT be called if the first argument to
230 "->connect()" looks like a valid DSN. This is determined by match the
231 DSN with "/^dbi:/i".
232
233 The function should return the same structure. For instance:
234
235 package My::Schema
236 use warnings;
237 use strict;
238 use base 'DBIx::Class::Schema::Config';
239 use LWP::Simple;
240 use JSON
241
242 # Load credentials from internal web server.
243 sub load_credentials {
244 my ( $class, $config ) = @_;
245
246 return decode_json(
247 get( "http://someserver.com/v1.0/database?key=somesecret&db=" .
248 $config->{dsn} ));
249 }
250
251 __PACKAGE__->load_classes;
252
254 Kaitlyn Parkhurst (SymKat) <symkat@symkat.com> ( Blog:
255 <http://symkat.com/> )
256
258 · Matt S. Trout (mst) <mst@shadowcat.co.uk>
259
260 · Peter Rabbitson (ribasushi) <ribasushi@cpan.org>
261
262 · Christian Walde (Mihtaldu) <walde.christian@googlemail.com>
263
264 · Dagfinn Ilmari Mannsåker (ilmari) <ilmari@ilmari.org>
265
266 · Matthew Phillips (mattp) <mattp@cpan.org>
267
269 This library is free software and may be distributed under the same
270 terms as perl itself.
271
273 The latest version of this software is available at
274 <https://github.com/symkat/DBIx-Class-Schema-Config>
275
276
277
278perl v5.32.0 2020-07-28 DBIx::Class::Schema::Config(3)