Friday, May 25, 2018

Interesting Ansible ipify problem

I had this interesting problem recently and was able to work around that problem (once I discovered it)

I was using the ansible functionality of 'ipify' to determine the public ip address of the host I was provisioning. It worked great and I used that fact to find the ethernet interface that was attached to that public ip address.

I ran it on a new host and it just didn't work.

After far too long of troubleshooting I discovered my problem. The ip address provided by 'ipify` was not the public ip address of the host I ran the playbook on. It was the public ip address of the http proxy that the system was using (...doh!!!). Don't get me wrong, this is the correct behavior of an application that uses http by respecting the proxy settings. However, ipify has no way to override the proxy setting.

I was able to solve it:

- name: delete public ip address file
  file:
    state: absent
    path: /tmp/public_ip_address

- name: set_facts | get my public IP
  get_url:
    url: http://ifconfig.co/ip
    use_proxy: no
    dest: /tmp/public_ip_address

- name: Slurp file with public ip address
  slurp:
    src: /tmp/public_ip_address
  register: slurpfile
 
- name: set_facts | set fact from ip address in slurped file
  set_fact:
    _public_ip_address: "{{ slurpfile['content'] | b64decode | ipaddr }}"

- name: set_facts | interface for public ip
  set_fact:
    public_interface: "{{ item }}"
  when: >
    (hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
    .get('ipv4', {}).get('address') == _public_ip_address
    or
    _public_ip_address in ((hostvars[inventory_hostname]['ansible_%s' % item]|default({}))
    .get('ipv4_secondaries'))|map(attribute='address')|list
  with_items:
    - "{{ ansible_interfaces }}"




Many thanks to user larsks that published a good way to iterate through the interfaces.

StackOverFlow discussion about Ansible iterating interface details

And shoutout to Flowroute ( https://www.flowroute.com/ )

Monday, January 29, 2018

Using Docker to solve my JAVA woes

Occasionally you encounter a problem that resurfaces every 6 months or so that you wish never would come back again. One of those problems is running multiple versions of Java (for various reasons) and toggling between those versions. "Jenv" works pretty well on a Mac, but sometimes when you are talking about libraries and java plugins it goes back to being complex.

For this last round, I took a different approach. What if I created a docker container that had everything I needed for that task? Then I could reuse that container whenever I needed and did not need to make any changes to my host system. My challenge this time around was connecting to an Avocent KVM switch that could only support a very old version of JAVA webstart.

I started with a basic Debian Wheezy container and added all the JAVA parts that I needed, then setup VNC to connect to the container. Downloading and launching the container is pretty easy if you follow the directions here https://hub.docker.com/r/paklids/jnlp-helper/ .

After that, there are a few other steps to follow.

#1 VNC to the container. I'm using RealVNC on a Mac, but you may use another method (My coworker used the Safari browser)

#2 After the window opens (using the correct password) then launch firefox from the text console
#3 Use firefox to browse to your Avocent KVM (or whatever site you need the older JAVA for - like those that use JNLP's)
#4 Accept any SSL exceptions. Even if you resolve the SSL problems with your appliance, you will still need to use an older version of JAVA which in itself is likely insecure. Now login to your device:
#5 Click on any of the links that uses Java Webstart (like JNLP links). Use the "Open with" context and select browse:
#6 Show other applications and then select "IcedTea Java Web Start"
At this point your Java Webstart application should start. I'll try to publish my Dockerfile so that if you need to tweak for your own purposes then you have a good base to start from. Enjoy!

Saturday, January 13, 2018

My first iPXE adventure!

I recently encountered the need to rebuild some bare-metal servers in one of our datacenters and fell into a strange requirement. I've built tons of PXE boot systems before (all different variations of kickstart) so I was stubborn when the recommendation for iPXE came along. 

"I can do this with standard PXE!" I said...

I was wrong.

This time around I needed iPXE for passing arguments to a dynamic build system. Initially, I was resistant. Then I bit the bullet and jumped into using iPXE. Boy was I glad, because it gave me flexibility that I hadn't used before. I'll document the process I used to configure my build box, but I wanted first to post my working iPXE boot config (also its the boot menu)


       

#!ipxe
# pulled from http://boot.ipxe.org/undionly.kpxe
set store mybuildserver.example.com

prompt --key 0x02 --timeout 1000 Press Ctrl-B for the iPXE command line... && shell ||

:boot_menu
menu iPXE Boot Menu
item localboot  Boot From Local Disk
item --gap --   --------- Operating Systems -------------
item ubuntu1604 Wipe and Install Ubuntu 16.04.3
item coreos     Wipe and Install CoreOS
item --gap --   ---------     Utilities     -------------
item gparted    GParted Partition Manager
item DBAN       Dariks Boot and Nuke       NOTE: at end press Alt-F4 and reboot
item --gap --   ---------     iPXE tools    -------------
item shell      iPXE Shell
item reboot     Reload iPXE

choose --default localboot --timeout 30000 target && goto ${target} ||
echo __NOTE: Cancel Enter Select Menu, Exit
exit

:localboot
sanboot --no-describe --drive 0x80 || goto boot_menu

:ubuntu1604
echo Starting Ubuntu Xenial installer for ${mac}
kernel http://${store}/ubuntu/install/netboot/ubuntu-installer/amd64/linux
initrd http://${store}/ubuntu/install/netboot/ubuntu-installer/amd64/initrd.gz
imgargs linux auto=true url=http://${store}/auto-16-preseed.cfg priority=critical preseed/interactive=false netcfg/choose_interface=enp3s0 vga=788 live-installer/net-image=http://${store}/ubuntu/install/filesystem.squashfs 
boot || goto boot_menu

:coreos
kernel http://${store}/coreos/coreos_production_pxe.vmlinuz
initrd http://${store}/coreos/coreos_production_pxe_image.cpio.gz
imgargs coreos_production_pxe.vmlinuz coreos.first_boot=1 coreos.autologin coreos.config.url=http://${store}:8080/ignition?mac=${mac:hexhyp}
boot || goto boot_menu

:gparted
kernel http://${store}/gparted/live/vmlinuz
initrd http://${store}/gparted/live/initrd.img
imgargs vmlinuz boot=live config components union=overlay username=user noswap noeject ip= vga=788 fetch=http://${store}/gparted/live/filesystem.squashfs
boot || goto boot_menu

:DBAN
kernel http://${store}/dban/dban.bzi
#imgargs dban.bzi nuke="dwipe"
imgargs dban.bzi nuke="dwipe --autonuke --method=zero" silent
boot || goto boot_menu

:shell
echo __NOTE: Type 'config' enter iPXE config setting, 'exit' return to boot menu.
shell
goto boot_menu