#!/usr/bin/perl # # Copyright 2015 Comcast Cable Communications Management, LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. use strict; use warnings; use feature qw(switch); use JSON; use File::Basename; use File::Path; use Fcntl qw(:flock); use MIME::Base64; use LWP::UserAgent; use Crypt::SSLeay; use Getopt::Long; $| = 1; my $date = `/bin/date`; chomp($date); print "$date\n"; # supported redhat/centos releases my %supported_el_release = ( "EL6" => 1, "EL7" => 1); my $dispersion = 300; my $retries = 5; my $wait_for_parents = 1; GetOptions( "dispersion=i" => \$dispersion, # dispersion (in seconds) "retries=i" => \$retries, "wait_for_parents=i" => \$wait_for_parents ); if ( $#ARGV < 1 ) { &usage(); } my $log_level = 0; $ARGV[1] = uc( $ARGV[1] ); given ( $ARGV[1] ) { when ("ALL") { $log_level = 255; } when ("TRACE") { $log_level = 127; } when ("DEBUG") { $log_level = 63; } when ("INFO") { $log_level = 31; } when ("WARN") { $log_level = 15; } when ("ERROR") { $log_level = 7; } when ("FATAL") { $log_level = 3; } when ("NONE") { $log_level = 1; } default { &usage(); } } my $traffic_ops_host = undef; my $TM_LOGIN = undef; if ( defined( $ARGV[2] ) ) { if ( $ARGV[2] !~ /^https*:\/\/.*$/ ) { &usage(); } else { $traffic_ops_host = $ARGV[2]; $traffic_ops_host =~ s/\/*$//g; } } else { &usage(); } if ( defined( $ARGV[3] ) ) { if ( $ARGV[3] !~ m/^.*\:.*$/ ) { &usage(); } else { $TM_LOGIN = $ARGV[3]; } } else { &usage(); } #### Script mode constants #### my $INTERACTIVE = 0; my $REPORT = 1; my $BADASS = 2; my $SYNCDS = 3; #### Logging constants for bit shifting #### my $ALL = 7; my $TRACE = 6; my $DEBUG = 5; my $INFO = 4; my $WARN = 3; my $ERROR = 2; my $FATAL = 1; my $NONE = 0; my $RELEASE = &os_version(); ( $log_level >> $DEBUG ) && print "DEBUG OS release is $RELEASE.\n"; my $script_mode = &check_script_mode(); &check_run_user(); &check_only_copy_running(); &check_log_level(); #### Constants to track update status #### my $UPDATE_TROPS_NOTNEEDED = 0; my $UPDATE_TROPS_NEEDED = 1; my $UPDATE_TROPS_SUCCESSFUL = 2; my $UPDATE_TROPS_FAILED = 3; #### Other constants ##### my $START_FAILED = 0; my $START_SUCCESSFUL = 1; my $ALREADY_RUNNING = 2; my $START_NOT_ATTEMPTED = 3; my $CLEAR = 0; my $PLUGIN_NO = 0; my $PLUGIN_YES = 1; #### Constants for config file changes #### my $CFG_FILE_UNCHANGED = 0; my $CFG_FILE_NOT_PROCESSED = 1; my $CFG_FILE_CHANGED = 2; my $CFG_FILE_PREREQ_FAILED = 3; my $CFG_FILE_ALREADY_PROCESSED = 4; #### LWP globals my $lwp_conn = &setup_lwp(); my $unixtime = time(); my $hostname_short = `/bin/hostname -s`; chomp($hostname_short); my $domainname = &set_domainname(); $lwp_conn->agent("$hostname_short-$unixtime"); my $TMP_BASE = "/tmp/ort"; my $cookie = &get_cookie( $traffic_ops_host, $TM_LOGIN ); # add any special yum options for your environment here; this variable is used with all yum commands my $YUM_OPTS = ""; ( $log_level >> $DEBUG ) && print "DEBUG YUM_OPTS: $YUM_OPTS.\n"; my $TS_HOME = "/opt/trafficserver"; my $TRAFFIC_LINE = $TS_HOME . "/bin/traffic_line"; my $out = `/usr/bin/yum $YUM_OPTS clean metadata 2>&1`; my $return = &check_output($out); my @config_files = (); #### Process reboot tracker my $reboot_needed = 0; my $traffic_line_needed = 0; my $sysctl_p_needed = 0; my $ntpd_restart_needed = 0; my $trafficserver_restart_needed = 0; #### Process runnning tracker my $ats_running = 0; my $teakd_running = 0; #### Process installed tracker my $installed_new_ssl_keys = 0; my %install_tracker; my $config_dirs = undef; my $cfg_file_tracker = undef; my $ssl_tracker = undef; my $ats_uid = getpwnam("ats"); ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### #### Start main flow ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### #### First and foremost, if this is a syncds run, check to see if we can bail. my $syncds_update = undef; if ( defined $traffic_ops_host ) { ($syncds_update) = &check_syncds_state(); } else { print "FATAL Could not resolve Traffic Ops host!\n"; exit 1; } #### Delete /tmp dirs older than one week if ( $script_mode == $BADASS || $script_mode == $INTERACTIVE || $script_mode == $SYNCDS ) { &smart_mkdir($TMP_BASE); &clean_tmp_dirs(); } ( my $my_profile_name, $cfg_file_tracker, my $my_cdn_name ) = &get_cfg_file_list( $hostname_short, $traffic_ops_host ); my $header_comment = &get_header_comment($traffic_ops_host); &process_packages( $hostname_short, $traffic_ops_host ); &process_chkconfig( $hostname_short, $traffic_ops_host ); #### First time &process_config_files(); #### Second time, in case there were new files added to the registry &process_config_files(); foreach my $file ( keys ( %{$cfg_file_tracker} ) ) { if ( exists($cfg_file_tracker->{$file}->{'remap_plugin_config_file'}) && $cfg_file_tracker->{$file}->{'remap_plugin_config_file'} ) { if ( exists($cfg_file_tracker->{$file}->{'change_applied'}) && $cfg_file_tracker->{$file}->{'change_applied'} ) { ( $log_level >> $DEBUG ) && print "\nDEBUG $file is a remap plugin config file, and was changed. remap.config needs touched. ========\n"; &touch_file('remap.config'); last; } } } if ( ($installed_new_ssl_keys) && !$cfg_file_tracker->{'ssl_multicert.config'}->{'change_applied'} ) { my $return = &touch_file('ssl_multicert.config'); if ($return) { if ( $syncds_update == $UPDATE_TROPS_NEEDED ) { $syncds_update = $UPDATE_TROPS_SUCCESSFUL; } $traffic_line_needed++; } } &start_restart_services(); if ( $sysctl_p_needed && $script_mode != $SYNCDS ) { &run_sysctl_p(); } &check_ntp(); if ( $script_mode != $REPORT ) { &update_trops(); } ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### #### End main flow ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### #### Subroutines ####-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#### sub os_version { my $release = "UNKNOWN"; if (`uname -r` =~ m/.+(el\d)\.x86_64/) { $release = uc $1; } exists $supported_el_release{$release} ? return $release : die("unsupported el_version: $release"); } sub usage { print "====-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-====\n"; print "Usage: ./traffic_ops_ort.pl [optional flags]\n"; print "\t = interactive - asks questions during config process.\n"; print "\t = report - prints config differences and exits.\n"; print "\t = badass - attempts to fix all config differences that it can.\n"; print "\t = syncds - syncs delivery services with what is configured in Traffic Ops.\n"; print "\n"; print "\t => ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, NONE\n"; print "\n"; print "\t = URL to Traffic Ops host. Example: https://trafficops.company.net\n"; print "\n"; print "\t => Example: 'username:password' \n"; print "\n\t[optional flags]:\n"; print "\t\tdispersion=