package PVE::API2::Ceph::Cfg; use strict; use warnings; use PVE::Ceph::Tools; use PVE::Cluster qw(cfs_read_file); use PVE::JSONSchema qw(get_standard_option); use PVE::RADOS; use PVE::Tools qw(file_get_contents); use base qw(PVE::RESTHandler); __PACKAGE__->register_method ({ name => 'index', path => '', method => 'GET', description => "Directory index.", permissions => { user => 'all' }, parameters => { additionalProperties => 0, properties => { node => get_standard_option('pve-node'), }, }, returns => { type => 'array', items => { type => "object", properties => {}, }, links => [ { rel => 'child', href => "{name}" } ], }, code => sub { my ($param) = @_; my $result = [ { name => 'raw' }, { name => 'db' }, { name => 'value' }, ]; return $result; }}); __PACKAGE__->register_method ({ name => 'raw', path => 'raw', method => 'GET', proxyto => 'node', permissions => { check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1], }, description => "Get the Ceph configuration file.", parameters => { additionalProperties => 0, properties => { node => get_standard_option('pve-node'), }, }, returns => { type => 'string' }, code => sub { my ($param) = @_; PVE::Ceph::Tools::check_ceph_inited(); my $path = PVE::Ceph::Tools::get_config('pve_ceph_cfgpath'); return file_get_contents($path); }}); __PACKAGE__->register_method ({ name => 'db', path => 'db', method => 'GET', proxyto => 'node', protected => 1, permissions => { check => ['perm', '/', [ 'Sys.Audit', 'Datastore.Audit' ], any => 1], }, description => "Get the Ceph configuration database.", parameters => { additionalProperties => 0, properties => { node => get_standard_option('pve-node'), }, }, returns => { type => 'array', items => { type => 'object', properties => { section => { type => "string", }, name => { type => "string", }, value => { type => "string", }, level => { type => "string", }, 'can_update_at_runtime' => { type => "boolean", }, mask => { type => "string" }, }, }, }, code => sub { my ($param) = @_; PVE::Ceph::Tools::check_ceph_inited(); my $rados = PVE::RADOS->new(); my $res = $rados->mon_command( { prefix => 'config dump', format => 'json' }); foreach my $entry (@$res) { $entry->{can_update_at_runtime} = $entry->{can_update_at_runtime}? 1 : 0; # JSON::true/false -> 1/0 } return $res; }}); my $SINGLE_CONFIGKEY_RE = qr/[0-9a-z\-_\.]+:[0-9a-zA-Z\-_]+/i; my $CONFIGKEYS_RE = qr/^(:?${SINGLE_CONFIGKEY_RE})(:?[;, ]${SINGLE_CONFIGKEY_RE})*$/; __PACKAGE__->register_method ({ name => 'value', path => 'value', method => 'GET', proxyto => 'node', protected => 1, permissions => { check => ['perm', '/', [ 'Sys.Audit' ]], }, description => "Get configured values from either the config file or config DB.", parameters => { additionalProperties => 0, properties => { node => get_standard_option('pve-node'), 'config-keys' => { type => "string", typetext => "
:[;
:]", pattern => $CONFIGKEYS_RE, description => "List of
: items.", } }, }, returns => { type => 'object', description => "Contains {section}->{key} children with the values", }, code => sub { my ($param) = @_; PVE::Ceph::Tools::check_ceph_inited(); # Ceph treats '-' and '_' the same in parameter names, stick with '-' my $normalize = sub { my $t = shift; $t =~ s/_/-/g; return $t; }; my $requested_keys = {}; for my $pair (PVE::Tools::split_list($param->{'config-keys'})) { my ($section, $key) = split(":", $pair); $section = $normalize->($section); $key = $normalize->($key); $requested_keys->{$section}->{$key} = 1; } my $config = {}; my $rados = PVE::RADOS->new(); my $configdb = $rados->mon_command( { prefix => 'config dump', format => 'json' }); for my $s (@{$configdb}) { my ($section, $name, $value) = $s->@{'section', 'name', 'value'}; my $n_section = $normalize->($section); my $n_name = $normalize->($name); $config->{$n_section}->{$n_name} = $value if defined $requested_keys->{$n_section} && $n_name eq $n_name; } # read ceph.conf after config db as it has priority if settings are present in both my $config_file = cfs_read_file('ceph.conf'); # cfs_read_file to get it parsed for my $section (keys %{$config_file}) { my $n_section = $normalize->($section); next if !defined $requested_keys->{$n_section}; for my $key (keys %{$config_file->{$section}}) { my $n_key = $normalize->($key); $config->{$n_section}->{$n_key} = $config_file->{$section}->{$key} if $requested_keys->{$n_section}->{$n_key}; } } return $config; }});