#!/usr/bin/perl # 1. Make the RHN Satellite profile name the same as 'hostname -s' # # 2. Delete any old RHN Satellite profiles for this host name # # 3. Create a new config channel named the same as the host (this config channel may already exist) # # 4. Subscribe to the new config channel # # 5. Check to see if the SSH host keys are in the config channel #If the keys are in the config channel, do nothing more as they'll be picked up after the script runs. #Otherwise check sat01.tdms:/export/ssh// for the keys. If they're there then upload the to Satellite # # 6. Examine IP address and set the group membership use strict; use warnings; use Data::Dumper; use File::Basename; use File::Copy; use Frontier::Client; use MIME::Base64; use NetAddr::IP; use Socket; use Sys::Hostname; use RHNSession; my ($client, $session) = RHNSession::Session; my $systems = $client->call('system.list_user_systems', $session); my $host = hostname; my $prog = basename $0; my $tmpdir = "/tmp/$prog.$$"; my $satellite = "sw02.hpdms"; my (@ids, @channels, $counter); my $sid = RHNSession::GetSID; print "My name is $host, my system ID is $sid\n"; die "I don't know my own name, quitting now.\n" if $host eq 'unknown'; # Shorten hostname if required for my $system (@$systems) { my ($sys_id, $sys_name); $sys_id = $system->{'id'}; $sys_name = $system->{'name'}; next unless $sys_id == $sid; if ($system->{'name'} eq 'unknown') { print "My profile name is 'unknown', changing it to '$host'...\n"; $client->call('system.setProfileName', $session, $system->{'id'}, $host); } } # Because we might have made changes on the Satellite server, refresh the system list $systems = $client->call('system.list_user_systems', $session); # Delete old entries in Satellite for my $sys(sort { $a->{'name'} ge $b->{'name'} } @$systems) { next unless $sys->{'name'} eq $host; next if $sid == $sys->{'id'}; print "$sys->{'id'} has my host name, killing it now\n"; $client->call('system.delete_systems', $session, $sys->{'id'}); } print "\nCurrently subscribed to these config channels\n"; my $channels = $client->call('system.config.listChannels', $session, $sid); my @subscribed_configs; my $subscribed = 0; my $make_sat_client = 0; if ($channels) { my $i = 0; print "Rank\tName (Label)\n"; for my $channel (@$channels) { $i++; $subscribed = 1 if ($channel->{'label'} eq $host); push @subscribed_configs, $channel->{'label'}; print "$i\t$channel->{'name'} ($channel->{'label'})\n"; } } else { print "No channels subscribed, this can't be a GoodThing(TM)\n"; # Assume running from make_sat_client $client->call('system.config.setChannels', $session, $sid, 'Global'); $make_sat_client = 1; } # csk = custom system key my $csk = $client->call('system.custominfo.listAllKeys', $session); # Get our IP address my $location; my $iaddr = gethostbyname($host) || ''; my $ip = $iaddr ? inet_ntoa($iaddr) : undef; $ip = new NetAddr::IP($ip); my $groups = $client->call('system.listGroups', $session, $sid); my %Groups; foreach my $group (@$groups) { $Groups{$group->{system_group_name}} = $group->{id}; } # Based on our IP, what zone are we in and what is our location? my $business = ""; foreach my $key (@$csk) { next unless $key->{label} =~ m/^zone-/ or $key->{label} =~ m/^location-/; # The IP address ranges for the zones are stored in the description for my $prefix (split(/\s/, $key->{description})) { $prefix = new NetAddr::IP($prefix); if ($ip->within($prefix)) { if ($key->{label} =~ m/^zone-/) { # Set the group membership to the zone if we match my $group = (split('-', $key->{label}, 2))[1]; # $client->call('system.setGroupMembership', $session, $sid, Groups{$group}, 1); print "Would have set group to $group\n"; } elsif ($key->{label} =~ m/^location-/) { $location = (split('-', $key->{label}, 2))[1]; # $client->call('system.setGroupMembership', $session, $sid, $Groups{$location}, 1); print "Would have set location to $location\n"; } } } } if ($location) { @subscribed_configs = ($location, @subscribed_configs); } open(RELEASE, "/etc/redhat-release") or die "Couldn't open /etc/redhat-release: $!"; while () { $_ =~ m/(\d)/; #$client->call('system.setGroupMembership', $session, $sid, $Group{"el$1"}, 1); print "Would have joined 'el$1'\n"; } close(RELEASE); if ($subscribed == 0) { print "Now subscribing to channel '$host'\n"; my $chan_exist = $client->call('configchannel.channelExists', $session, $host); if ($chan_exist) { print "Config channel '$host' already exists, not creating again...\n"; } else { $client->call('configchannel.create', $session, $host, $host, "Files specific to host $host"); print "Created config channel '$host'\n" unless $@; } my @sids; push @sids, $sid; print Dumper @subscribed_configs; @subscribed_configs = ($host, @subscribed_configs); foreach my $chan ($host, @subscribed_configs) { eval { $client->call('system.config.setChannels', $session, \@sids, $chan); }; } $channels = $client->call('system.config.listChannels', $session, $sid); my $i = 0; print "Now subscribed to config channels:\n"; print "Rank\tName (Label)\n"; for my $channel (@$channels) { $i++; push @subscribed_configs, $channel->{'label'}; print "$i\t$channel->{'name'} ($channel->{'label'})\n"; } } else { print "Already subscribed to config channel '$host'\n"; } $counter = 0; my $files = $client->call('configchannel.listFiles', $session, $host); for my $file (@$files) { next unless $file->{'path'} =~ m|/etc/ssh/ssh_host_|; $counter++; } if ($counter lt 6) { print "SSH host keys are *not* on the Satellite server\n"; # The files don't exist so we need ssh to create them if (! -f "/etc/ssh/ssh_host_key") { `/sbin/service sshd start ; /sbin/service sshd stop` if ($make_sat_client == 0); } opendir(DIR, "/etc/ssh/"); my @ssh_files = grep /^ssh_host_/, readdir DIR; closedir(DIR); for my $filename (@ssh_files) { $filename = "/etc/ssh/".$filename; print "$filename\n"; my ($filetype, $buffer) = (1, ""); my %fileinfo; if (-f $filename) { $fileinfo{'contents'} = do { local( *ARGV, $/ ); @ARGV=$filename; <> }; $filetype = 0; if (-T $filename or -z $filename) { print "$filename is a text file, appending newline char\n"; $fileinfo{'contents'} = $fileinfo{'contents'}."\n\r"; } else { print "$filename is a binary file, encoding as MIME base 64\n"; $fileinfo{'contents'} = $client->base64(encode_base64($fileinfo{'contents'})) unless (-T $filename or -z $filename); } } $fileinfo{'owner'} = getpwuid((stat($filename))[4]); $fileinfo{'group'} = getgrgid((stat($filename))[5]); $fileinfo{'permissions'} = $client->string(sprintf("%04o", (stat($filename))[2] & 07777)); # The below is done as an eval because if the API call fails the script will bomb out eval { $client->call('configchannel.createOrUpdatePath', $session, $host, $filename, $client->string($filetype), \%fileinfo); }; } } else { print "SSH host keys are on the Satellite server\nOur work here is done.\n"; } # Lets play nicely and logout when we're finished $client->call('auth.logout', $session); exit;