Rex

 view release on metacpan or  search on metacpan

lib/Rex/Config.pm  view on Meta::CPAN

#
# (c) Jan Gehring <jan.gehring@gmail.com>
#

=head1 NAME

Rex::Config - Handles Rex configuration

=head1 SYNOPSIS

 use Rex::Config;

 # set a config option
 Rex::Config->set_exec_autodie(TRUE);

 # get value of a config option
 my $user = Rex::Config->get_user();

=head1 DESCRIPTION

This module holds all configuration options for Rex, and also allows you to specify your own ones for your modules.

Please take a look at L<Rex::Commands> first, which provides convenience wrappers for many of these options.

While it's possible to use the methods below to set a configuration option directly, their main intended purpose is to be used as internal plumbing, and to provide an escape hatch in case there are no better alternatives.

=head1 EXPORTED METHODS

=cut

package Rex::Config;

use v5.14.4;
use warnings;

our $VERSION = '1.16.1'; # VERSION

use Rex::Helper::File::Spec;
use Rex::Logger;
use YAML;
use Data::Dumper;
use Rex::Require;
use Symbol;

our (
  $user,                        $password,
  $port,                        $timeout,
  $max_connect_fails,           $password_auth,
  $key_auth,                    $krb5_auth,
  $public_key,                  $private_key,
  $parallelism,                 $log_filename,
  $log_facility,                $sudo_password,
  $ca_file,                     $ca_cert,
  $ca_key,                      $path,
  $no_path_cleanup,             $set_param,
  $environment,                 $connection_type,
  $distributor,                 $template_function,
  $SET_HANDLER,                 $HOME_CONFIG,
  $HOME_CONFIG_YAML,            %SSH_CONFIG_FOR,
  $sudo_without_locales,        $sudo_without_sh,
  $no_tty,                      $source_global_profile,
  $source_profile,              %executor_for,
  $allow_empty_groups,          $use_server_auth,
  $tmp_dir,                     %openssh_opt,
  $use_cache,                   $cache_type,
  $use_sleep_hack,              $report_type,
  $do_reporting,                $say_format,
  $exec_autodie,                $verbose_run,
  $disable_taskname_warning,    $proxy_command,
  $task_call_by_method,         $fallback_auth,
  $register_cmdb_template,      $check_service_exists,
  $set_no_append,               $use_net_openssh_if_present,
  $use_template_ng,             $use_rex_kvm_agent,
  $autodie,                     $task_chaining_cmdline_args,
  $waitpid_blocking_sleep_time, $write_utf8_files,
  $default_auth,                $augeas_commands_prepend,
  $local_augeas_backend,
);

# some defaults
%executor_for = (
  perl   => "perl",
  python => "python",
  ruby   => "ruby",
  bash   => "bash",
);

=head2 set_autodie

=head2 get_autodie

Sets and gets the value of the C<$autodie> configuration variable.

This controls whether Rex should C<die()> if there's an error while executing L<file system commands that are supposed to change the contents|Rex::Commands::Fs#Changing-content>.

Default is C<undef>.

=cut

sub set_autodie {
  my $class = shift;
  $autodie = shift;
}

sub get_autodie {
  return $autodie;
}

=head2 set_use_net_openssh_if_present

lib/Rex/Config.pm  view on Meta::CPAN

  }
  return $key_auth;
}

=head2 set_krb5_auth

=head2 get_krb5_auth

Sets and gets the value of the C<$krb5_auth> configuration variable, which can also be set by setting the C<REX_AUTH_TYPE> environment variable to C<krb5>.

This controls whether Rex should use the L<Kerberos 5|Rex::Commands#krb5_auth> authentication method.

Default is C<undef>.

=cut

sub set_krb5_auth {
  my $class = shift;
  $password_auth = 0;
  $key_auth      = 0;
  $krb5_auth     = shift || 1;
}

sub get_krb5_auth {
  if ( exists $ENV{REX_AUTH_TYPE} && $ENV{REX_AUTH_TYPE} eq "krb5" ) {
    return 1;
  }
  return $krb5_auth;
}

=head2 set_public_key

=head2 get_public_key

Sets and gets the value of the C<$public_key> configuration variable.

This controls which L<public key|Rex::Commands#public_key> Rex should use when using L<Net::SSH2> for connections.

Default is C<undef>.

=cut

sub set_public_key {
  my $class = shift;
  $public_key = shift;
}

sub has_public_key {
  return get_public_key();
}

sub get_public_key {
  if ( exists $ENV{REX_PUBLIC_KEY} ) { return $ENV{REX_PUBLIC_KEY}; }
  if ($public_key) {
    return $public_key;
  }

  return;
}

=head2 set_private_key

=head2 get_private_key

Sets and gets the value of the C<$private_key> configuration variable.

This controls which L<private key|Rex::Commands#private_key> Rex should use with L<Rex::Commands::Rsync> or when using L<Net::SSH2> for connections.

Default is C<undef>.

=cut

sub set_private_key {
  my $class = shift;
  $private_key = shift;
}

sub has_private_key {
  return get_private_key();
}

sub get_private_key {
  if ( exists $ENV{REX_PRIVATE_KEY} ) { return $ENV{REX_PRIVATE_KEY}; }
  if ($private_key) {
    return $private_key;
  }

  return;
}

=head2 set_parallelism

=head2 get_parallelism

Sets and gets the value of the C<$parallelism> configuration variable.

This controls how many hosts Rex should connect to in L<parallel|Rex::Commands#parallelism>.

Default is C<1>.

=cut

sub set_parallelism {
  my $class = shift;
  $parallelism = $_[0];
}

sub get_parallelism {
  my $class = shift;
  return $parallelism || 1;
}

=head2 set_log_filename

=head2 get_log_filename

Sets and gets the value of the C<$log_filename> configuration variable.

This controls which file Rex should use for L<logging|Rex::Commands#logging>.

Default is C<undef>.

=cut

sub set_log_filename {
  my $class = shift;
  $log_filename = shift;
}

sub get_log_filename {
  my $class = shift;
  return $log_filename;
}

=head2 set_log_facility

=head2 get_log_facility

Sets and gets the value of the C<$log_facility> configuration variable.

This controls which log facility Rex should use when L<logging|Rex::Commands#logging> to syslog.

Default is C<'local0'>.

=cut

lib/Rex/Config.pm  view on Meta::CPAN


sub get_log_facility {
  my $class = shift;
  return $log_facility || "local0";
}

=head2 set_environment

=head2 get_environment

Sets and gets the value of the C<$environment> configuration variable.

This controls which L<environment|Rex::Commands#environment> Rex should use.

Default is C<''>.

=cut

sub set_environment {
  my ( $class, $env ) = @_;
  $environment = $env;
}

sub get_environment {
  return $environment || "";
}

sub get_ssh_config_username {
  my $class = shift;
  my $param = {@_};

  if ( exists $param->{server}
    && exists $SSH_CONFIG_FOR{ $param->{server} }
    && exists $SSH_CONFIG_FOR{ $param->{server} }->{user} )
  {
    return $SSH_CONFIG_FOR{ $param->{server} }->{user};
  }

  return 0;
}

sub get_ssh_config_hostname {
  my $class = shift;
  my $param = {@_};

  if ( exists $param->{server}
    && exists $SSH_CONFIG_FOR{ $param->{server} }
    && exists $SSH_CONFIG_FOR{ $param->{server} }->{hostname} )
  {
    if ( $SSH_CONFIG_FOR{ $param->{server} }->{hostname} =~ m/^\%h(\.(.*))?/ ) {
      return $param->{server} . $1;
    }
    else {
      return $SSH_CONFIG_FOR{ $param->{server} }->{hostname};
    }
  }

  return 0;
}

sub get_ssh_config_private_key {
  my $class = shift;
  my $param = {@_};

  if ( exists $param->{server}
    && exists $SSH_CONFIG_FOR{ $param->{server} }
    && exists $SSH_CONFIG_FOR{ $param->{server} }->{identityfile} )
  {

    my $file     = $SSH_CONFIG_FOR{ $param->{server} }->{identityfile};
    my $home_dir = _home_dir();
    $file =~ s/^~/$home_dir/;

    return $file;
  }

  return 0;
}

sub get_ssh_config_public_key {
  my $class = shift;
  my $param = {@_};

  if ( exists $param->{server}
    && exists $SSH_CONFIG_FOR{ $param->{server} }
    && exists $SSH_CONFIG_FOR{ $param->{server} }->{identityfile} )
  {
    my $file     = $SSH_CONFIG_FOR{ $param->{server} }->{identityfile} . ".pub";
    my $home_dir = _home_dir();
    $file =~ s/^~/$home_dir/;
    return $file;
  }

  return 0;
}

sub get_connection_type {
  my $class = shift;

  if ( $^O !~ m/^MSWin/ && !$connection_type && $use_net_openssh_if_present ) {
    my $has_net_openssh = 0;
    eval {
      Net::OpenSSH->require;
      Net::SFTP::Foreign->require;
      $has_net_openssh = 1;
      1;
    };

    if ($has_net_openssh) {
      Rex::Logger::debug(
        "Found Net::OpenSSH and Net::SFTP::Foreign - using it as default");
      $connection_type = "OpenSSH";
      return "OpenSSH";
    }
  }

  if ( !$connection_type ) {
    my $has_net_ssh2 = 0;
    eval {
      Net::SSH2->require;
      $has_net_ssh2 = 1;

lib/Rex/Config.pm  view on Meta::CPAN


      #my ($key, $val) = ($line =~ m/^\s*([^\s]+)\s+=?\s*(.*)$/);
      $line =~ s/^\s*//g;
      my ( $key, $val_tmp ) = split( /[\s=]/, $line, 2 );
      $val_tmp =~ s/^[\s=]+//g;
      my $val = $val_tmp;

      $val =~ s/^\s+//;
      $val =~ s/\s+$//;
      for my $h (@host) {
        $ret{$h}->{ lc($key) } = $val;
      }
    }
  }

  return %ret;
}

sub import {
  read_ssh_config_file();
  read_config_file();
}

_register_config_handlers();

sub _register_config_handlers {
  __PACKAGE__->register_config_handler(
    base => sub {
      my ($param) = @_;

      for my $key ( keys %{$param} ) {

        if ( $key eq "keyauth" ) {
          $key_auth = $param->{keyauth};
          next;
        }

        if ( $key eq "passwordauth" ) {
          $password_auth = $param->{passwordauth};
          next;
        }

        if ( $key eq "passauth" ) {
          $password_auth = $param->{passauth};
          next;
        }

        my $ref_to_key        = qualify_to_ref( $key, __PACKAGE__ );
        my $ref_to_key_scalar = *{$ref_to_key}{SCALAR};

        ${$ref_to_key_scalar} = $param->{$key};
      }
    }
  );
}

_register_set_handlers();

sub _register_set_handlers {
  my @set_handler =
    qw/user password private_key public_key -keyauth -passwordauth -passauth
    parallelism sudo_password connection ca cert key distributor
    template_function port waitpid_blocking_sleep_time/;
  for my $hndl (@set_handler) {
    __PACKAGE__->register_set_handler(
      $hndl => sub {
        my ($val) = @_;
        if ( $hndl =~ m/^\-/ ) {
          $hndl = substr( $hndl, 1 );
        }
        if ( $hndl eq "keyauth" ) { $hndl = "key_auth"; $val = 1; }
        if ( $hndl eq "passwordauth" || $hndl eq "passauth" ) {
          $hndl = "password_auth";
          $val  = 1;
        }
        if ( $hndl eq "connection" ) { $hndl = "connection_type"; }
        if ( $hndl eq "ca" )         { $hndl = "ca_file"; }
        if ( $hndl eq "cert" )       { $hndl = "ca_cert"; }
        if ( $hndl eq "key" )        { $hndl = "ca_key"; }

        my $ref_to_hndl        = qualify_to_ref( $hndl, __PACKAGE__ );
        my $ref_to_hndl_scalar = *{$ref_to_hndl}{SCALAR};

        ${$ref_to_hndl_scalar} = $val;
      }
    );
  }
}

sub _home_dir {
  if ( $^O =~ m/^MSWin/ ) {
    return $ENV{'USERPROFILE'};
  }

  return $ENV{'HOME'} || "";
}

1;



( run in 1.016 second using v1.01-cache-2.11-cpan-524268b4103 )