Red Hat Satellite 6 Feature Overview: Importing Existing Hosts via the Bootstrap Script

Updated

Overview

The bootstrap script (bootstrap.py) provides a means to take existing Red Hat Enterprise Linux systems and migrate them into Satellite 6.

Example Use Cases

  • Migrate a client from Satellite 5 to Satellite 6, while properly configuring it with regards to content and configuration.
  • Migrate a client from Satellite 5 Proxy to Satellite 6, while properly configuring it with regards to content and configuration.
  • Migrate a client from one Satellite 6 to another.
  • Migrate a client from RHSM to an on-premise Satellite 6
  • Importing a client into Satellite 6 that was provisioned via some other tool.

Requirements

  • Red Hat Satellite 6.2 or higher
  • Managed Systems running Red Hat Enterprise Linux.
  • Installation of the katello-client-bootstrap package on each Satellite and/or Capsule. This package places the bootstrap.py file in /var/www/html/pub/bootstrap.py, making it accessible via HTTP/HTTPS.
  • Red Hat Subscription Manager(RHSM) to be installed.

Working with the bootstrap script in Red Hat Satellite 6.x

Bootstrap Script for migrating existing running systems to Satellite 6.x

What does the Script do?

  • Identify which systems management platform is the system registered to (Classic/Sat5 or None) then perform the following

Red Hat Classic & Satellite 5

  • Installing subscription-manager and its pre-requisite packages (updated yum & openssl)
  • Make an API call to Katello to create the Foreman Host associated with the user-specified Org/Location
  • Install the Katello consumer RPM
  • Running rhn-migrate-classic-to-rhsm (with the user-provided activation key) to get product certs on a system
  • registering the system to Foreman
  • Configuring the system with a proper puppet configuration pointing at Foreman
  • Removing/disabling old RHN Classic packages/daemons (rhnsd, osad, etc)

System not registered to any Red Hat Systems Management Platform:

  • Make an API call to Foreman to create the Foreman Host associated with the user-specified Org/Location
  • Install the Katello consumer RPM
  • Running subscription-manager (with the user-provided activation key) to register the system.
  • Configuring the system with a proper puppet configuration pointing at Foreman
  • Removing/disabling old RHN Classic packages/daemons (rhnsd, osad, etc)

Assumptions

  • The script will use only components that are present on all RHEL installations. We will not install additional packages, other than those explicitly required for Katello management, on the client system. (i.e., we could have used the python-requests module to make the API calls a lot more pleasant, but we couldn't justify the dependencies)
  • The activation key that provides access to a Content View which provides Puppet and other client-side tooling.
  • The system in question has python.
  • It is assumed that the user has root-level access on the host that the bootstrap script is being run on.
  • The administrator can approve puppet certificates if using Puppet. Alternatively, auto signing can be enabled for the system in question. (And be careful, auto-signing isn't one of those things you'd leave enabled forever)

User required inputs

  • Hostname of Satellite and/or Capsule host.
  • Username of user with privileges to add new hosts on Foreman via the API.
  • Password of the aforementioned user.
  • Location and Organization that the system is to be associated with.
  • Hostgroup that the client is to be associated with.
  • An Activation Key that provides a content view with access to Puppet and other tools.

Usage:

  • Normal usage of bootstrap.py script.

    
       # ./bootstrap.py -l admin \
         -s Satellite.example.com \
         -o Default_Organization \
         -L Default_Location \
         -g My_Hostgroup \
         -a My_Activation_Key
    
    

Help / Available options:

  • Obtain help using -h option.

    
       Foreman Bootstrap Script
       This script is designed to register new systems or to migrate an existing system to a Foreman server with Katello
       Usage: bootstrap.py [options]
    
       Options:
         -h, --help            show this help message and exit
         -s foreman_fqdn, --server=foreman_fqdn
                               FQDN of Foreman OR Capsule - omit https://
         -l LOGIN, --login=LOGIN
                               Login user for API Calls
         -p PASSWORD, --password=PASSWORD
                               Password for specified user. Will prompt if omitted
         --fqdn=FQDN           Set an explicit FQDN, overriding detected FQDN from
                               socket.getfqdn(), currently detected as
                               client.example.com
         --legacy-login=LOGIN  Login user for Satellite 5 API Calls
         --legacy-password=PASSWORD
                               Password for specified Satellite 5 user. Will prompt
                               if omitted
         --legacy-purge        Purge system from the Legacy environment (e.g. Sat5)
         -a ACTIVATIONKEY, --activationkey=ACTIVATIONKEY
                               Activation Key to register the system
         -P, --skip-puppet     Do not install Puppet
         --skip-foreman        Do not create a Foreman host. Implies --skip-puppet.
                               When using --skip-foreman, you MUST pass the
                               Organization's LABEL, not NAME
         -g HOSTGROUP, --hostgroup=HOSTGROUP
                               Title of the Hostgroup in Foreman that the host is to
                               be associated with
         -L LOCATION, --location=LOCATION
                               Title of the Location in Foreman that the host is to
                               be associated with
         -O OPERATINGSYSTEM, --operatingsystem=OPERATINGSYSTEM
                               Title of the Operating System in Foreman that the host
                               is to be associated with
         --partitiontable=PARTITIONTABLE
                               Name of the Partition Table in Foreman that the host
                               is to be associated with
         -o ORG, --organization=ORG
                               Name of the Organization in Foreman that the host is
                               to be associated with
         -S ARGS, --subscription-manager-args=ARGS
                               Which additional arguments shall be passed to
                               subscription-manager
         --rhn-migrate-args=ARGS
                               Which additional arguments shall be passed to rhn-
                               migrate-classic-to-rhsm
         -u, --update          Fully Updates the System
         -v, --verbose         Verbose output
         -f, --force           Force registration (will erase old katello and puppet
                               certs)
         --add-domain          Automatically add the client's domain to Foreman
         --puppet-noop         Configure Puppet agent to only run in noop mode
         --remove              Instead of registering the machine to Foreman remove it
         -r RELEASE, --release=RELEASE
                               Specify release version
         -R, --remove-obsolete-packages
                               Remove old Red Hat Network and RHUI Packages (default)
         --download-method=DOWNLOADMETHOD
                               Method to download katello-ca-consumer package (e.g.
                               http or https)
         --no-remove-obsolete-packages
                               Don't remove old Red Hat Network and RHUI Packages
         --unmanaged           Add the server as unmanaged. Useful to skip
                               provisioning dependencies.
         --rex                 Install Foreman's SSH key for remote execution.
         --rex-user=REMOTE_EXEC_USER
                               Local user used by Foreman's remote execution feature.
         --enablerepos=enablerepos
                               Repositories to be enabled via subscription-manager -
                               comma separated
         --skip=SKIP           Skip the listed steps (choices: ['foreman', 'puppet',
                               'migration', 'prereq-update', 'katello-agent',
                               'remove-obsolete-packages'])
         --ip=IP               IPv4 address of the primary interface in Foreman
                               (defaults to the address used to make a request to
                               Foreman
    

Example run of the bootstrap.py script

In the below examples assume the following environment:

  • Organization = RedHat
  • Location = RDU
  • Username = admin
  • Hostgroup = RHEL7/Crash
  • Satellite FQDN = satellite.example.com

Example invocation 1

This example invocation is for a system that we wish to register via satellite.example.com. (with Satellite version 6.2)

  • First, download the bootstrap script from the Capsule to the client.

    
       [root@client-1 ~]# wget http://satellite.example.com/pub/bootstrap.py
       --2016-04-26 11:55:01--  http://satellite.example.com/pub/bootstrap.py
       Resolving satellite.example.com (satellite.example.com)... 172.17.14.2
       Connecting to satellite.example.com (satellite.example.com)|172.17.14.2|:80... connected.
       HTTP request sent, awaiting response... 200 OK
       Length: 19714 (19K)
       Saving to: ‘bootstrap.py’
       
       100%[===================================================================================================================================>] 19,714      --.-K/s   in 0s
    
       2016-04-26 11:55:01 (313 MB/s) - ‘bootstrap.py’ saved [19714/19714]
    
    
  • Make the script executable

    [root@client-1 ~]# chmod +x bootstrap.py
    
  • Run the script

Content from satellite.example.com is not included.https://satellite.example.com/pulp/repos/RedHat/crash/rhel7_base/content/dist/rhel/server/7/7Server/x86_64/os/repodata/productid.gz:%20[Errno%20-1]%20Metadata%20file%20does%20not%20match%20checksumorcert 10]



#### Approving the client's Puppet Certificate

- At this point, the client will wait indefinitely until an administrator approves the puppet certificate. This can be done in the Satellite Web UI via **Infrastructure**->**Capsules**, and selecting **Certificates** in the WebUI, as shown below **click to enlarge**

[![ALT TEXT](https://access.redhat.com/sites/default/files/attachments/bootstrap_sign_puppet_certificate.small__0.png)](https://access.redhat.com/sites/default/files/attachments/bootstrap_sign_puppet_certificate.png  "Sign Puppet Certificate")

#### Finishing the bootstrap process.

- After approving the client's puppet certificate, return to the guest to see the remainder of the bootstrap process completing.


  Info: Creating a new SSL key for client-1.example.com
  Info: Caching certificate for ca
  Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
  Info: Creating a new SSL certificate request for client-1.example.com
  Info: Certificate Request fingerprint (SHA256): AF:EF:DF:8B:83:58:1C:E2:F1:30:E4:EC:BA:6B:E1:FC:9B:B4:38:71:1A:55:77:69:48:AE:94:9D:2F:1C:FD:31
  Info: Caching certificate for ca
  
  Info: Caching certificate for client-1.example.com
  Info: Caching certificate_revocation_list for ca
  Warning: Unable to fetch my node definition, but the agent run will continue:
  Warning: Error 400 on SERVER: Failed to find client-1.example.com via exec: Execution of '/etc/puppet/node.rb client-1.example.com' returned 1:
  Info: Retrieving pluginfacts
  Info: Retrieving plugin
  Notice: /File[/var/lib/puppet/lib/puppet]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/provider]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/provider/file_line]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/parser]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/ensure_packages.rb]/ensure: defined content as '{md5}fbed5c0c9bf82b7746e01f15f89d184f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_hash.rb]/ensure: defined content as '{md5}e9cfaca68751524efe16ecf2f958a9a0'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/count.rb]/ensure: defined content as '{md5}9eb74eccd93e2b3c87fd5ea14e329eba'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_bool.rb]/ensure: defined content as '{md5}a712634a000024398b3c6cd4ecc46463'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/get_module_path.rb]/ensure: defined content as '{md5}d4bf50da25c0b98d26b75354fa1bcc45'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_ip_address.rb]/ensure: defined content as '{md5}a714a736c1560e8739aaacd9030cca00'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_numeric.rb]/ensure: defined content as '{md5}93ddc9d4c0834a5e5e0562d7b3cdce91'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/fqdn_rand_string.rb]/ensure: defined content as '{md5}9ac5f18e563094aee62ef7586267025d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/bool2str.rb]/ensure: defined content as '{md5}6334ac6d24a8aa49a2243fb425f47311'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/delete.rb]/ensure: defined content as '{md5}cec92c5de6d748c8dc93ca7d25ac1c68'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_domain_name.rb]/ensure: defined content as '{md5}6ca1f2708add756a6803b29d593d5830'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/has_ip_address.rb]/ensure: defined content as '{md5}ee207f47906455a5aa49c4fb219dd325'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_absolute_path.rb]/ensure: defined content as '{md5}51c81d562fcc6c2df49ce5cfefd721ff'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/has_key.rb]/ensure: defined content as '{md5}7cd9728c38f0b0065f832dabd62b0e7e'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/flatten.rb]/ensure: defined content as '{md5}25777b76f9719162a8bab640e5595b7a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/private.rb]/ensure: defined content as '{md5}1500a21d5cf19961c5b1d476df892d92'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/ceiling.rb]/ensure: defined content as '{md5}dfa9b1c75ce89344026b3b5aed2d190f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/max.rb]/ensure: defined content as '{md5}f652fd0b46ef7d2fbdb42b141f8fdd1d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_augeas.rb]/ensure: defined content as '{md5}61e828e7759ba3e1e563e1fdd68aa80f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/has_ip_network.rb]/ensure: defined content as '{md5}b4d726c8b2a0afac81ced8a3a28aa731'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/convert_base.rb]/ensure: defined content as '{md5}c3b3e59a49318af98dcb88aed7156629'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_mac_address.rb]/ensure: defined content as '{md5}6dd3c96437d49e68630869b0b464e7f2'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/getparam.rb]/ensure: defined content as '{md5}4dd7a0e35f4a3780dcfc9b19b4e0006e'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_array.rb]/ensure: defined content as '{md5}72b29289b8af1cfc3662ef9be78911b8'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/assert_private.rb]/ensure: defined content as '{md5}1365284f9e474ecec24cfe43ee8e7cf4'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/pw_hash.rb]/ensure: defined content as '{md5}d82221f667050026cd6d155432a31802'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/loadyaml.rb]/ensure: defined content as '{md5}6da5dc9256c9e7a6549bb15c72cb9f9d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/empty.rb]/ensure: defined content as '{md5}b4ad0c3c00cbc56f745fbc05af1efa00'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/load_module_metadata.rb]/ensure: defined content as '{md5}805c5476a6e7083d133e167129885924'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/defined_with_params.rb]/ensure: defined content as '{md5}ffab4433d03f32b551f2ea024a2948fc'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/bool2num.rb]/ensure: defined content as '{md5}f953f5fc094c2ae3908a72d8840ba291'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/union.rb]/ensure: defined content as '{md5}3cf57ea53f2522f586264feb67293cd6'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/hash.rb]/ensure: defined content as '{md5}9d072527dfc7354b69292e9302906530'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/suffix.rb]/ensure: defined content as '{md5}109279db4180441e75545dbd5f273298'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/type3x.rb]/ensure: defined content as '{md5}f9bf4de8341afb0c677c26b40ec8a2b2'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/floor.rb]/ensure: defined content as '{md5}42cad4c689231a51526c55a6f0985d1f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/intersection.rb]/ensure: defined content as '{md5}c8f4f8b861c9c297c87b08bdbfb94caa'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/basename.rb]/ensure: defined content as '{md5}c61952b3f68fd86408c84fca2c3febb1'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/prefix.rb]/ensure: defined content as '{md5}e377fd64bd63dde6c9660aa75aca4942'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_integer.rb]/ensure: defined content as '{md5}c665be82686aa4729959bb42c66a7510'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/try_get_value.rb]/ensure: defined content as '{md5}2ef0cc8141dfd72f45b5e854dde26a0f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/swapcase.rb]/ensure: defined content as '{md5}b17a9f3cb0271451d309e4b4f52dd651'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/to_bytes.rb]/ensure: defined content as '{md5}65437027687b6172173b3a211a799e37'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/has_interface_with.rb]/ensure: defined content as '{md5}e135f09dbecc038c3aa9ae03127617ef'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/deep_merge.rb]/ensure: defined content as '{md5}d83696855578fb81b64b9e92b9c7cc7c'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/unix2dos.rb]/ensure: defined content as '{md5}b1f5087fcaca69d9395094204cce887a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/lstrip.rb]/ensure: defined content as '{md5}20a9b1fa077c16f34e0ef5448b895698'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_array.rb]/ensure: defined content as '{md5}875ca4356cb0d7a10606fb146b4a3d11'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/min.rb]/ensure: defined content as '{md5}0d2a1b7e735ab251c5469e735fa3f4c6'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/sort.rb]/ensure: defined content as '{md5}504b033b438461ca4f9764feeb017833'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/dos2unix.rb]/ensure: defined content as '{md5}be8359a5106a7832be4180e8207dd586'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/merge.rb]/ensure: defined content as '{md5}f3dcc5c83440cdda2036cce69b61a14b'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/seeded_rand.rb]/ensure: defined content as '{md5}2ad22e7613d894ae779c0c5b0e65dade'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/member.rb]/ensure: defined content as '{md5}2b5d7fb8f87f1c7d195933c57ca32e91'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/base64.rb]/ensure: defined content as '{md5}ae25adf92295df67ebd9edfabc9ecdd6'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/capitalize.rb]/ensure: defined content as '{md5}da131748a9d32da9eb0b6438e39377eb'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/values.rb]/ensure: defined content as '{md5}066a6e4170e5034edb9a80463dff2bb5'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/chomp.rb]/ensure: defined content as '{md5}2b7dc42f9967edd34cfa0ba9a97229ca'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/unique.rb]/ensure: defined content as '{md5}c1bb4a8aeebd09ba3e4c8bc3702cfd60'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/shuffle.rb]/ensure: defined content as '{md5}d50f72b0aeb921e64d2482f62488e2f3'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/num2bool.rb]/ensure: defined content as '{md5}605c12fa518c87ed2c66ae153e0686ce'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/join_keys_to_values.rb]/ensure: defined content as '{md5}f29da49531228f6ca5b3aa0df00a14c2'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/concat.rb]/ensure: defined content as '{md5}2a12f95e94669129827ee2f2a26349c3'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/any2array.rb]/ensure: defined content as '{md5}a81e71d6b67a551d38770ba9a1948a75'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/camelcase.rb]/ensure: defined content as '{md5}71c67b71eac4b7f46a0dd22cb915d2e6'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/pick.rb]/ensure: defined content as '{md5}bf01f13bbfe2318e7f6a302ac7c4433f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/rstrip.rb]/ensure: defined content as '{md5}b4e4ada41f7c1d2fcad073ce6344980f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/str2bool.rb]/ensure: defined content as '{md5}e380cfbc3395404ac8232ff960b22bca'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/abs.rb]/ensure: defined content as '{md5}32161bd0435fdfc2aec2fc559d2b454b'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/dirname.rb]/ensure: defined content as '{md5}8a5579f9a9a13fd737ba65eccf8e6d5a'
  Notice: /File[/var/lib/puppet/lib/puppet/functions]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/functions/type_of.rb]/ensure: defined content as '{md5}71e19f89e167c45ec691ea6c7d319625'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/parseyaml.rb]/ensure: defined content as '{md5}1e6a3a38eb2c1b0329ae1ebaaa0f062c'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/grep.rb]/ensure: defined content as '{md5}5682995af458b05f3b53dd794c4bf896'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/ntp_dirname.rb]/ensure: defined content as '{md5}109e37ef3261f95ae19fcbccb280042d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/difference.rb]/ensure: defined content as '{md5}e31b95fbaf974cf853a510177368bfb9'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/squeeze.rb]/ensure: defined content as '{md5}541f85b4203b55c9931d3d6ecd5c75f8'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/downcase.rb]/ensure: defined content as '{md5}73121616d73339cf8dd10e0de61a6c50'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_string.rb]/ensure: defined content as '{md5}2bd9a652bbb2668323eee6c57729ff64'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_absolute_path.rb]/ensure: defined content as '{md5}94ea1869c438d23f7f659c87ced8080a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/delete_at.rb]/ensure: defined content as '{md5}6bc24b79390d463d8be95396c963381a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/size.rb]/ensure: defined content as '{md5}ab3b5b8cf2369d76969a7cb2564e018f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_hash.rb]/ensure: defined content as '{md5}8c7d9a05084dab0389d1b779c8a05b1a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/keys.rb]/ensure: defined content as '{md5}eb6ac815ea14fbf423580ed903ef7bad'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/uriescape.rb]/ensure: defined content as '{md5}d912ba09ba3f58c70988e662e05ffbe8'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_ipv4_address.rb]/ensure: defined content as '{md5}ea5a7e87f51fc5a961cdc7369b3c9d00'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_ipv6_address.rb]/ensure: defined content as '{md5}4699238e4cad60e7e1428905523eaeb7'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_integer.rb]/ensure: defined content as '{md5}438c7fdd25f7f6a208ac48c9b75a390f'
  Notice: /File[/var/lib/puppet/lib/puppet/provider/file_line/ruby.rb]/ensure: defined content as '{md5}0b7ed2917e70902b5c40362370edcbb0'
  Notice: /File[/var/lib/puppet/lib/puppet/type]/ensure: created
  Notice: /File[/var/lib/puppet/lib/puppet/type/anchor.rb]/ensure: defined content as '{md5}bbd36bb49c3b554f8602d8d3df366c0c'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_numeric.rb]/ensure: defined content as '{md5}60b0c6d5b8b170ea77498a8580bd3158'
  Notice: /File[/var/lib/puppet/lib/facter]/ensure: created
  Notice: /File[/var/lib/puppet/lib/facter/service_provider.rb]/ensure: defined content as '{md5}66cc42526eae631e306b397391f1f01c'
  Notice: /File[/var/lib/puppet/lib/facter/util]/ensure: created
  Notice: /File[/var/lib/puppet/lib/facter/util/puppet_settings.rb]/ensure: defined content as '{md5}9f1d2593d0ae56bfca89d4b9266aeee1'
  Notice: /File[/var/lib/puppet/lib/facter/facter_dot_d.rb]/ensure: defined content as '{md5}878e161fc0c3682fb1a554fe28b8be60'
  Notice: /File[/var/lib/puppet/lib/facter/root_home.rb]/ensure: defined content as '{md5}35702ae0c7410ec4d2101113e2f697fa'
  Notice: /File[/var/lib/puppet/lib/facter/package_provider.rb]/ensure: defined content as '{md5}1473dd2347de164f583bbf66dcfc956a'
  Notice: /File[/var/lib/puppet/lib/facter/puppet_vardir.rb]/ensure: defined content as '{md5}c7ddc97e8a84ded3dd93baa5b9b3283d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/delete_values.rb]/ensure: defined content as '{md5}39b147f7d369bb5f809044b6341954a2'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/reject.rb]/ensure: defined content as '{md5}689f6a7c961a55fe9dcd240921f4c7f9'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/range.rb]/ensure: defined content as '{md5}76f693d1dd50ffee409e58ff6d9a58bb'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_slength.rb]/ensure: defined content as '{md5}5f0db124caae4866f474a60c589ba632'
  Notice: /File[/var/lib/puppet/lib/facter/rh_certificates.rb]/ensure: defined content as '{md5}532b80a6c0c04b121504b70fd9ec7c1d'
  Notice: /File[/var/lib/puppet/lib/facter/pe_version.rb]/ensure: defined content as '{md5}60d47406026c8201e51394227ddf780d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/pick_default.rb]/ensure: defined content as '{md5}ad3ea60262de408767786d37a54d45dc'
  Notice: /File[/var/lib/puppet/lib/puppet/functions/is_a.rb]/ensure: defined content as '{md5}9dad7f8c9b75348cd97aca986ac0b29a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/join.rb]/ensure: defined content as '{md5}a285a05c015ae278608f6454aef211ea'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/strip.rb]/ensure: defined content as '{md5}85d70ab95492e3e4ca5f0b5ec3f284a9'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/upcase.rb]/ensure: defined content as '{md5}8decededec9eb33e58f961eb86f0888f'
  Notice: /File[/var/lib/puppet/lib/puppet/type/file_line.rb]/ensure: defined content as '{md5}3969f0a0443825260c2c678aaeab2792'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/time.rb]/ensure: defined content as '{md5}8cb0b8320c60b4a21725634154a9f1db'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_bool.rb]/ensure: defined content as '{md5}e693b7c4b5366cff1380b6e0c7dd7b11'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_string.rb]/ensure: defined content as '{md5}cf6a20877a27b1073d63fdd522af50bb'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/reverse.rb]/ensure: defined content as '{md5}b234b54b8cd62b2d67ccd70489ffdccf'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/type.rb]/ensure: defined content as '{md5}4709f7ab8a8aad62d77a3c5d91a3aa08'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/zip.rb]/ensure: defined content as '{md5}a89d5e802bc1e63e52020c2ddbaaca2c'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/ensure_resource.rb]/ensure: defined content as '{md5}de703fe63392b939fc2b4392975263de'
  Notice: /File[/var/lib/puppet/lib/facter/rsyslog_version.rb]/ensure: defined content as '{md5}cf7c75552375b53a17cca28524a11d6d'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_re.rb]/ensure: defined content as '{md5}53613813ba02914f2692f0edd7e12fab'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_function_available.rb]/ensure: defined content as '{md5}628428bbcd9313ce09783d9484330e09'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/str2saltedsha512.rb]/ensure: defined content as '{md5}49afad7b386be38ce53deaefef326e85'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/delete_undef_values.rb]/ensure: defined content as '{md5}b32d4a3925753b2eb2c318cbd7f14404'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/fqdn_rotate.rb]/ensure: defined content as '{md5}770d510a2e50d19b2dd42b6edef3fb1f'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_ip_address.rb]/ensure: defined content as '{md5}4d8423bf126b102cf88489aec9a10186'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/values_at.rb]/ensure: defined content as '{md5}325a899e0201e8df5bd483fec6f12d76'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/getvar.rb]/ensure: defined content as '{md5}344f1ce85dcb7512d37e8702ccbabb66'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/strftime.rb]/ensure: defined content as '{md5}e02e01a598ca5d7d6eee0ba22440304a'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/chop.rb]/ensure: defined content as '{md5}0ec76f54afd94201f35785dfeb2092b5'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/is_float.rb]/ensure: defined content as '{md5}10e0d3ecf75fac15e415aee79acf70dc'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/parsejson.rb]/ensure: defined content as '{md5}600f4d747678f55e163025ba87488af2'
  Notice: /File[/var/lib/puppet/lib/puppet/parser/functions/validate_cmd.rb]/ensure: defined content as '{md5}57b3b128c035802fb67754eed3a88475'
  Info: Loading facts
  Info: Caching catalog for client-1.example.com
  Info: Applying configuration version '1461689797'
  Info: Creating state file /var/lib/puppet/state/state.yaml
  Notice: Finished catalog run in 0.12 seconds
  [SUCCESS], [2016-04-26 12:56:57], [/usr/bin/puppet agent --test --noop --tags no_such_tag --waitforcert 10], completed successfully.
  
  [RUNNING], [2016-04-26 12:56:57], [/sbin/service puppet restart]
  Redirecting to /bin/systemctl restart  puppet.service
  [SUCCESS], [2016-04-26 12:56:57], [/sbin/service puppet restart], completed successfully.



#### Inspecting your bootstrapped host via the UI

- In the Satellite Web UI, via **All Hosts**->**Hosts**, ensure that your client is connected to the correct Hostgroup, as shown below. **click to enlarge**


[![ALT TEXT](https://access.redhat.com/sites/default/files/attachments/bootstrap_client-1.example.com_.small__0.png)](https://access.redhat.com/sites/default/files/attachments/bootstrap_client-1.example.com_.png  "client-1.example.com")

## Video


<div class="media-youtube-video media-youtube-1">
  <iframe class="media-youtube-player" id="media-youtube-lkyy-1eiaok" width="1139" height="641" title="Satellite 6.2 Feature Overview: Importing Existing Hosts via the Bootstrap Script" src="https://www.youtube.com/embed/LKyy_1eIaok?wmode=opaque&enablejsapi=1&playerapiid=media-youtube-lkyy-1eiaok" frameborder="0" allowfullscreen>Video of Satellite 6.2 Feature Overview: Importing Existing Hosts via the Bootstrap Script</iframe>
</div>

## Advanced usages

## Example usages of bootstrap.py


### Registering a system to Satellite

- This is one of the most standard workflows with bootstrap.py. This sets up the system for content / configuration (via puppet) & provisioning.


./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash


### Registering a system to Satellite 6, omitting puppet setup.

- There are times where you wish to not install puppet, perhaps you have a differing or existing configuration management system.


./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash \
   --skip-puppet


### Registering a system to Satellite 6, for content only.

This usage leverages the `--skip-foreman` switch, which does not require username/password authentication.

**NOTES**

- the `--skip-foreman` switch implies `--skip-puppet`
- When using `--skip-foreman`, it is expected that the organization specified  (via `--organization|-o`) is specified via **LABEL**, not **NAME**.


./bootstrap.py -s satellite.example.com \

   -a ak_Reg_To_Dev_EL7 \
   -o "Red_Hat" \
   --skip-foreman



### Migrating a system from Red Hat Network (RHN) or Satellite 5 to Satellite 6.

Bootstrap.py detects the presence of `/etc/syconfig/rhn/systemid` and a valid connection to RHN/Satellite 5 as an indicator that the system is registered to a legacy platform. In these use-cases, bootstrap will call `rhn-classic-migrate-to-rhsm` to ensure the system is migrated properly from RHN or Satellite 5.

By default, bootstrap.py does not delete the system's profile from the legacy platform. This is done to keep the systems record for audit/accounting reasons. If it is desired to remove the legacy profile from RHN/Satellite 5, the `--legacy-purge` switch can be used.

**NOTES**:

- The `--legacy-purge` switch requires a user account on RHN/Satellite 5 with permissions to remove the systems in question.
- The `--legacy-login` and `--legacy-password` options allow the correct RHN/Satellite 5 username/password to be provided to bootstrap.py.
- bootstrap.py will prompt the user for the Legacy Password if not provided via CLI parameter.


./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash \
   --legacy-purge \
   --legacy-login rhn-user


### Migrating a system from one Satellite 6 installation to another.

There are times where it is necessary to migrate clients from one Satellite 6 installation to another. For instance, in lieu of upgrading an older Satellite 6 installation, you choose to build a new installation in parallel. Bootstrap.py can then be used to migrate clients from one Satellite 6 installation to another. Simply provide the `--force` option, and bootstrap.py will remove the previous `katello-ca-consumer-*` package (from the old system), and will install the `katello-ca-consumer-*` package (from the new system), and continue registration as usual.

### Enabling additional repositories at registration time.

- It is recommended to set which repositories that you want to be enabled on your activation keys via the Satellite Web UI or via `hammer activation-key product-content`. However, older versions of `subscription-manager` (versions < 1.10) do not support product content overrides. The `--enablerepos` switch accepts a comma-separated lists of repositories that are passed to `subscription-manager` that will be enabled at registration time.


./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash \
   --enablerepos=rhel-7-server-satellite-tools-6.2-rpms, rhel-7-server-optional-rpms


### Creating a domain for a host at registration time.

- To create a host record, the DNS domain of a host needs to exist  (in Satellite) prior to running bootstrap.py. If the domain does not exist, it can be added via the `--add-domain` switch.


hostname

client.linux.example.com

./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash

[NOTIFICATION], [2016-12-05 09:15:29], [Domain linux.example.com doesn't exist in Foreman, consider using the --add-domain option.]



- Run the script again including the `--add-domain` option


#./bootstrap.py -l admin
-s satellite.example.com
-o "Red Hat"
-L RDU
-g "RHEL7/Crash"
-a ak-Reg_To_Crash
--add-domain

[RUNNING], [2016-12-05 09:19:10], [Calling Foreman API to create domain linux.example.com associated with the org & location] [RUNNING], [2016-12-05 09:19:10], [Calling Foreman API to create a host entry associated with the group & org] [SUCCESS], [2016-12-05 09:19:10], [Successfully created host client.linux.example.com], completed successfully.



### Enabling Remote Execution

- Satellite 6.2 introduced the [Remote Execution](https://access.redhat.com/articles/2464671) feature to allow remote management. Bootstrap.py now includes the `--rex` & `--rex-user` features which allow the administrator to deploy the required SSH keys.



  # ./bootstrap.py -l admin \
      -s satellite.example.com \
      -o "Red Hat" \
      -L RDU \
      -g "RHEL7/Crash" \
      -a ak-Reg_To_Crash \
      --rex \
      --rex-user root
  
  [SUCCESS], [2016-12-02 06:37:09], [/usr/bin/yum -y remove rhn-setup rhn-client-tools yum-rhn-plugin rhnsd rhn-check rhnlib spacewalk-abrt spacewalk-oscap osad 'rh-*-rhui-client'], completed successfully.

  [NOTIFICATION], [2016-12-02 06:37:09], [Foreman's SSH key was added to /root/.ssh/authorized_keys]

Key was added successfully.



- **Caution**: Careful while using `--rex` option cause `-r` option is available to set release version. 

- Check the **root** users authorized key file.


cat ~/.ssh/authorized_keys ssh-rsa AAAAB3Nz.... foreman-proxy@satellite.example.com



### Skipping particular steps:

Sometimes, you may want to skip certain steps of the bootstrapping process. the `--skip` switch provides this. It currently has the following parameters

* `foreman` - Skips any Foreman setup steps. (equivalent to the `--skip-foreman` option)
* `puppet` - Does not install puppet (equivalent to the `--skip-puppet` option)
* `migration` - Skips RHN/Spacewalk registration detection. This option prevents `rhn-classic-migrate-to-rhsm` from timing out and failing on RHN/Spacewalk systems that aren't available.
* `prereq-update` - Skips update of `yum`, `openssl` and `python`
* `katello-agent` - Does not install the `katello-agent` package
* `remove-obsolete-packages` - Does not remove the Classic/RHN/Spacewalk/RHUI packages.  (equivalent to `--no-remove-obsolete-packages`)

**Note:** it is strongly preferred to use the `--skip` option in lieu of the individual `--skip-foreman`, `--skip-puppet`, and `--no-remove-obsolete-packages` options.

- For example.


./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash \
   --skip prereq-update --skip migration


### Providing an arbitrary Fully Qualified Domain Name.

Many users have either hostnames that are short (`hostname -f` or python's `socket.getfqdn` returns a hostname that isn't an FQDN) or non-RFC compliant (containing a character such as an underscore `-` which fails Foreman's hostname validation.

In many cases, the user cannot update his/her system to provide a FQDN. bootstrap.py provides the `--fqdn` which allows the user to specify the FQDN that will be reported to Foreman

**Prerequisites**

- The user needs to set to **False** the `create_new_host_when_facts_are_uploaded` and ` create_new_host_when_report_is_uploaded` options. If these options are not set, a host entry will be created based upon the facts provided by facter.  This can be done with hammer.


hammer settings set
--name create_new_host_when_facts_are_uploaded
--value false hammer settings set
--name create_new_host_when_report_is_uploaded
--value false



Example Usage

- General use of `bootstrap.py`.


hostname -f

node-100

python -c 'import socket; print socket.getfqdn()'

node-100

./bootstrap.py -l admin \

   -s satellite.example.com \
   -o "Red Hat" \
   -L RDU \
   -g "RHEL7/Crash" \
   -a ak-Reg_To_Crash \
   --fqdn node-100.example.com


### Changing the method bootstrap uses to download the katello-ca-consumer RPM

- By default, the bootstrap script uses HTTP to download the `katello-ca-consumer` RPM. In some environments, it is desired to only allow HTTPS between the client and Foreman. the `--download-method` option can be used to change the download method that bootstrap uses from HTTP to HTTPS.


./bootstrap.py -l admin
-s satellite.example.com
-o "Red Hat"
-L RDU
-g "RHEL7/Crash"
-a ak-Reg_To_Crash
--download-method https



## Providing the IP address to Foreman

Foreman requires the IP address of the machine to perform remote execution or re-deploy the machine using kickstart.

- On machines with multiple interfaces or multiple addresses on one interface, it might be needed to override the auto-detection of the address and provide a specific address to Foreman.


./bootstrap.py -l admin
-s satellite.example.com
-o "Red Hat"
-L RDU
-g "RHEL7/Crash"
-a ak-Reg_To_Crash
--ip 192.0.2.23



### New Features & bugfixes included in katello-client-bootstrap version 1.2.x (included with Satellite 6.2.5)

- Bootstrap now disassociates a host if it is associated with a compute resource prior to removing it.
- Bootstrap now defaults to removing RHN and RHUI packages (see the `--remove-obsolete-packages` switch. `--no-remove-obsolete-packages` negates this behavior.
- Bootstrap properly supports i686 systems.
- Bootstrap properly handles HTTP 20x responses from the API
- Bootstrap properly fails if a minimal version of the `subscription-manager-migration` package is not found as older versions of `rhn-migrate-classic-to-rhsm` do not support activation keys
- Bootstrap now has the `--add-domain` switch to add the domain of a registering host if it doesn't exist.
- Bootstrap properly checks to see if the user is root prior to running.
- Bootstrap ensures that subscription-manager passes the FQDN in rhsm request to prevent duplicate host entries
- Bootstrap properly configures the system for Remote Execution (see the `--rex` and `--rex-user` switches)
- Bootstrap no longer requires the Location as a mandatory parameter.
- Bootstrap updates python to prevent issues with gopher.
- Bootstrap now supports the `--enablerepos` switch to support older versions of subscription-manager which do not support enabling repos via activation keys.
- Bootstrap ensures that the `productid` and `subscription-manager` plugins are properly enabled.
- Bootstrap now gracefully fails if the user is attempting to run the script on a system already registered to Katello.
- Bootstrap now properly removes Katello CA certificates installed manually or via the consumer RPM
- Bootstrap now properly migrates systems using activation keys that have spaces
- Bootstrap now defaults to using `--force` when calling `rhn-migrate-classic-to-rhsm`, allowing systems using cloned channels to be migrated
- Bootstrap no longer prompts for a password when `--skip-foreman` is used.


### New Features & bugfixes included in katello-client-bootstrap version 1.3.x (included with Satellite 6.2.9)


* Bootstrap now (re)starts rhsmcertd upon completion as some users may have it disabled. 
* Bootstrap now supports the `--fqdn` option, allowing the user to specify an arbitrary hostname that would be used instead of the detected hostname
* Bootstrap now supports the `--download-method` option which allows the download of the `katello-ca-consumer-latest` package to occur via HTTPs
* Bootstrap now gracefully handles if the user uses the `--rex` switch against a Capsule that does not have the SSH feature enabled. 
* Bootstrap now supports the `--ip` option, allowing the user to override the auto-detected IP of the machine. 
* Bootstrap now works on systems with non-standard `GEM_PATH` environment variables
* Bootstrap now supports a modular skip option `--skip`, which allows the user to skip specific sections of the script. (**Example:** : `--skip foreman` to skip the Foreman parts of the script). This allows us to deliver additional skip options without requiring a new switch for each. 
* Bootstrap ensures that `/etc/rhsm/facts/` exits prior to running. 
* fixed evaluation codes when external commands are called via `commands.getstatusoutput`

For more KB articles/solutions related to Red Hat Satellite 6.x Bootstrap Script Issues, please refer to the [Red Hat Satellite Consolidated Troubleshooting Article for Red Hat Satellite 6.x Bootstrap Script Issues.](https://access.redhat.com/articles/6427081)


Product(s)
Category
Components
Article Type