Nov 14, 2017 - Additional Ansible Windows Facts

Ansible is a great tool to manage any Linux or Windows host. However it is missing some key tools and features. Here is a playbook and instructions to gather all installed programs on a Windows host.

Start with creating a new role, I named mine facts.

Create the facts\tasks\main.yml file and add the following

---
- name: create Scripts dir
  win_file:
    path: C:\Scripts
    state: directory 

- name: create Scripts facts dir
  win_file:
    path: C:\Scripts\facts
    state: absent        

- name: copy custom facts file
  win_copy:
    src: getFacts.ps1
    dest: C:\Scripts\

- name: gather extra facts
  setup:
    fact_path: C:\Scripts

- name: Set intermediate fact
  set_fact:
    vars_hack: ""

- name: set program facts
  set_fact:
    one_fact: ansible_getFacts
    var_hack:  "" 
            
- name: delete json file 
  file:
    path: "/.json"
    state: absent
  failed_when: false
  delegate_to: localhost

- name: Dump all vars
  action: template src=templates/dumpall.j2 dest="/.json"
  delegate_to: localhost

- name: add to db
  script: app.py
  delegate_to: localhost
  ignore_errors: true



Now create the facts/files/getFacts.ps1 file and add the follwoing below. This file will be copied to each Windows host and run return a dictionary of all installed programs.

#sourced from https://hindenes.com/trondsworking/2016/11/05/using-ansible-as-a-software-inventory-db-for-your-windows-nodes/
$packages = Get-WmiObject -Class Win32_Product
$returnpackages = @{}
foreach ($package in $packages)
{
   $subpackagedictionary = @{"Name" = $Package.Name; "Version" = $Package.Version; "Caption" = $Package.Caption;}
   $returnpackages.Add($Package.Name, $subpackagedictionary)
}
#Write-Host $returnpackages."Google Chrome".Name
#Write-Host $returnpackages."Google Chrome".Version
$returnpackages

For debugging purposes you may want to create JSON files from the returned dictionary. To do so create a facts/templates/dumpall.j2 and add the following.


  {{ vars_hack | to_json }}

Create the facts\files\app.py and add the following below. This files erases passwords dumped in the the json files.

#!/usr/bin/env python
# orginal found at https://hindenes.com/trondsworking/2016/11/05/using-ansible-as-a-software-inventory-db-for-your-windows-nodes/

import os
import json

from os import listdir
from os.path import isfile, join

tempfolder = '../roles/facts/files/data/json/'

if not os.path.isdir(tempfolder):
  os.makedirs(tempfolder)

onlyfiles = [f for f in listdir(tempfolder) if isfile(join(tempfolder, f))]

for file in onlyfiles:
  host_name = str(file).replace('.json','')  ##I am using host ips, to use hostnames use str(file).split(".")[3]
  with open(os.path.join(tempfolder, file),'r+') as data_file:
      data = json.load(data_file)
      data['ansible_password'] = ''
      data['ansible_password_ad'] = ''
      data_file.close()
  with open(tempfolder+'/'+file, 'w+') as outfile:
    json.dump(data, outfile, sort_keys=True, indent=2, separators=(',', ': '))
  outfile.close()

Create one last file the vars file for the role. Create vars/main.yml and add the following.

json_files: '../roles/facts/files/data/json/'
host_program_csv: '../roles/facts/files/data/programs'

Now install the redis service. For Centos 7

yum install redis
systemctl enable redis
systemctl start redis

Generate a hash for redis

echo "redis-password-string" | sha256sum 

Edit the redis config file in /etc/redis.confand find the line requirepass and insert the generated hash

Edit your base ansible.cfg usualy in the first directory of your ansible setup and add the line

fact_caching_connection = <redis-ip>:6379:0:<redis-hash>

Updated: 2/7/2019

Feb 25, 2017 - SMTP to SMS relay

This script will send SMS via various smtp relays.

import smtplib

# Use sms gateway provided by mobile carrier:
# alltel         number@message.Alltel.com 
# at&t:          number@mms.att.net
# boost:         number@myboostmobile.com
# google voice   number@@txt.voice.google.com (needs work)
# metro pcs:     number@mymetropcs.com
# sprint:        number@page.nextel.com
# straight talk  number@mypixmessages.com
# t-mobile:      number@tmomail.net
# us cellular:   number@mms.uscc.net  
# verizon:-       number@vtext.com
# virgin:        number@vmpix.com

server = smtplib.SMTP( "smtp.gmail.com", 587 )
server.ehlo()
server.starttls()
server.ehlo()
server.login( 'Google username', '<Google app password >' )


#server.sendmail( '<from>', '<number>@tmomail.net', 'Hello!' )

server.sendmail( '<sending phone number>', '<receiving phone numver>@<domain.com>', 'Leory Jenkins!!!!' )

Jan 17, 2017 - Python WSGI

How to run a python pyramid application under apache2(httpd) using the mod_wgsi.

Create application user

  useradd appdeploy

Edit /etc/passwd

  appdeploy:x:<uid>:<gid>:appdeploy:/<home>/<directory>:/sbin/nologin

Create an apache2 config file under /etc/httpd/conf.d/

<virtuallHost *:80>
  ServerName archive.fqdn.com

# Use only 1 Python sub-interpreter.  Multiple sub-interpreters
# play badly with C extensions.  See
# http://stackoverflow.com/a/10558360/209039
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIDaemonProcess pyramid user=appdeploy    group=appdeploy  threads=4 \
   python-path=/var/www/archive/temp_py/lib/python2.7/site-packages
WSGIScriptAlias / /var/www/archive/pyramid.wsgi

<Directory /var/www/archive>
  WSGIProcessGroup pyramid
  Order allow,deny
  Allow from all
</Directory>

</VirtualHost>

Create a WSGI file in the application directory that will be called by the apache2 service.

import os,sys,site

os.environ['PYTHON_EGG_CACHE'] = '/var/www/archive/temp_py'

from pyramid.paster import get_app, setup_logging
ini_path = '/var/www/archive/production.ini'
#setup_logging(ini_path)
application = get_app(ini_path, 'main')