Conferència: SmartHome usant Arduino, Raspberry PI i més
El dia 12 de febrer al vespre vaig fer una conferència a la FIB (Facultat d’Informàtica de Barcelona) dins de la UPC (Universitat Politècnica de Catalunya). En aquesta xerra vaig estar explicant com vaig convertint en realitat un somni que vaig tenir quan era petit, estic parlant de domotitzar la casa. Gràcies a enginys com l’Arduino i la Raspberry PI a més d’aplicacions com l’OpenHab podem fer assequible allò que si anem a grans marques comercials es fa caríssim pel meu pressupost.
En aquest enllaç podeu trobar les transparències de: SmartHome usant Arduino Raspberry i més i el video el teniu disponible al servidor de la FIB.
Ara també teniu disponible el video a youtube:
i podeu veure les transparències des d’aquest mateix post:
Espero els vostres feedbacks als comentaris, desitjo que ús sigui útil.
Turn on virtual machines in VMWare ESXi
Next commands are very useful when you don’t have access to the vSphere UI and you have to access to VMWare Hypervisor using SSH or console:
# get the list of virtual machines vim-cmd vmsvc/getallvms # get the state of a VM with #id: VM_ID vim-cmd vmsvc/power.getstate VM_ID # turn on the virtual machine with #id: VM_ID vim-cmd vmsvc/power.on VM_ID
Another option to turn on the virtual machine using an Ansible playbook:
- hosts: vmware gather_facts: false tasks: - vsphere_guest: vcenter_hostname: "X.X.X.X" username: "{{ hostvars[inventory_hostname].ansible_ssh_user|quote }}" password: "{{ hostvars[inventory_hostname].ansible_ssh_pass|quote }}" guest: "NAME_OF_THE_VM" state: "powered_on" delegate_to: localhost
pfSense: unlock SSH
After several tries without success to pfSense’s SSH server the port is blocked by a service called “sshlockout”. If you need to unblock the SSH service run the command from shell:
pfctl -t sshlockout -T flush
In the end that command only removes the rules in table “sshlockout” in firewall entries.
New Ansible Role uploaded to Ansible Galaxy
A long time ago I wrote an entry post about how to set up the SMTP in linux boxes using a relay system you can find the post here: Relay mail from your server without MTA. Remember that SSMTP is not a SMTP service for your system but it’s more than enough for all servers that don’t work as a mail servers. Historically Unix/Linux uses sendmail command to send system notifications but usually this mails are lost because system configurations are not completed. My advice in this sense is use SSMTP.
In the past I used to use SSMTP with a GMail account but security constraints in Google mail services make it difficult to configure today. The new alternative is set up a free Mandrill account as a relay host. Mandrill is a Mailchimp service that allows you to send a lot of emails without problems and there is a free account that allows to send up to 12.000 mails per month free, more than enough usually. If you don’t know how to set up a Mailchimp account the best option to learn how to do it is follow the support documentation it’s very good IMHO.
When you have a lot of linux machines to administer you need something fastly replicable. As you know use Ansible is a very good option. Then I developed a new Ansible role to set up Mandrill accounts to SSMTP services massively using Ansible.
The Ansible role has been uploaded here: ssmtp-mandrill and the source code of the roles is in my github. Remember to install the role in your Ansible is easy:
ansible-galaxy install oriol.rius.ssmtp-mandrill
Then you only need to create your own playbook using the role and don’t forget to setup the variables with the Mandrill account settings.
Ansible and Windows Playbooks
Firstly let me introduce a Windows service called: “Windows Remote Manager” or “WinRM”. This is the Windows feature that allows remote control of Windows machines and many other remote functionalities. In my case I have a Windows 7 laptop with SP1 and PowerShell v3 installed.
Secondly don’t forget that Ansible is developed using Python then a Python library have to manage the WinRM protocol. I’m talking about “pywinrm“. Using this library it’s easy to create simple scripts like that:
#!/usr/bin/env python import winrm s = winrm.Session('10.2.0.42', auth=('the_username', 'the_password')) r = s.run_cmd('ipconfig', ['/all']) print r.status_code print r.std_out print r.std_err
This is a remote call to the command “ipconfig /all” to see the Windows machine network configuration. The output is something like:
$ ./winrm_ipconfig.py 0 Windows IP Configuration Host Name . . . . . . . . . . . . : mini7w Primary Dns Suffix . . . . . . . : Node Type . . . . . . . . . . . . : Hybrid IP Routing Enabled. . . . . . . . : No WINS Proxy Enabled. . . . . . . . : No DNS Suffix Search List. . . . . . : ymbi.net Ethernet adapter GigaBit + HUB USB: Connection-specific DNS Suffix . : ymbi.net Description . . . . . . . . . . . : ASIX AX88179 USB 3.0 to Gigabit Ethernet Adapter Physical Address. . . . . . . . . : 00-23-56-1C-XX-XX DHCP Enabled. . . . . . . . . . . : Yes Autoconfiguration Enabled . . . . : Yes Link-local IPv6 Address . . . . . : fe80::47e:c2c:8c25:xxxx%103(Preferred) IPv4 Address. . . . . . . . . . . : 10.2.0.42(Preferred) Subnet Mask . . . . . . . . . . . : 255.255.255.192 Lease Obtained. . . . . . . . . . : mi�rcoles, 28 de enero de 2015 12:41:41 Lease Expires . . . . . . . . . . : mi�rcoles, 28 de enero de 2015 19:17:56 Default Gateway . . . . . . . . . : 10.2.0.1 DHCP Server . . . . . . . . . . . : 10.2.0.1 DHCPv6 IAID . . . . . . . . . . . : 2063606614 DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-15-F7-BF-36-xx-C5-xx-03-xx-xx DNS Servers . . . . . . . . . . . : 10.2.0.27 10.2.0.1 NetBIOS over Tcpip. . . . . . . . : Enabled ...
Of course, it’s possible to run Powershell scripts like the next one which shows the system memory:
$strComputer = $Host Clear $RAM = WmiObject Win32_ComputerSystem $MB = 1048576 "Installed Memory: " + [int]($RAM.TotalPhysicalMemory /$MB) + " MB"
The Python code to run that script is:
#!/usr/bin/env python import winrm ps_script = open('scripts/mem.ps1','r').read() s = winrm.Session('10.2.0.42', auth=('the_username', 'the_password')) r = s.run_ps(ps_script) print r.status_code print r.std_out print r.std_err
and the output:
$ ./winrm_mem.py 0 Installed Memory: 2217 MB
In the end it’s time to talk about how to create an Ansible Playbook to deploy anything in a Windows machine. As always the first thing that we need is a hosts file. In the next example there are several ansible variables needed to run Ansible Windows modules on WinRM, all of them are self-explanatory:
[all] 10.2.0.42
[all:vars]
ansible_ssh_user=the_username ansible_ssh_pass=the_password ansible_ssh_port=5985 #winrm (non-ssl) port ansible_connection=winrm
The first basic example could be a simple playbook that runs the ‘ipconfig’ command and registers the output in an Ansible variable to be showed later like a debug information:
- name: test raw module hosts: all tasks: - name: run ipconfig raw: ipconfig register: ipconfig - debug: var=ipconfig
The command and the output to run latest example:
$ ansible-playbook -i hosts ipconfig.yml PLAY [test raw module] ******************************************************** GATHERING FACTS *************************************************************** ok: [10.2.0.42] TASK: [run ipconfig] ********************************************************** ok: [10.2.0.42] TASK: [debug var=ipconfig] **************************************************** ok: [10.2.0.42] => { "ipconfig": { "invocation": { "module_args": "ipconfig", "module_name": "raw" }, "rc": 0, "stderr": "", "stdout": "\r\nWindows IP Configuration\r\n\r\n\r\nEthernet adapter GigaBit ... ] } } PLAY RECAP ******************************************************************** 10.2.0.42 : ok=3 changed=0 unreachable=0 failed=0
As always Ansible have several modules, not only the ‘raw’ module. I committed two examples in my Github account using a module to download URLs and another one that runs Powershell scripts.
My examples are done using Ansible 1.8.2 installed in a Fedora 20. But main problems I’ve found are configuring Windows 7 to accept WinRM connections. Next I attach some references that helped me a lot:
- pywinrm Github project notes., easy to trace errors than Ansible.
- Ansible notes about Windows.
- How to enable WinRM via Group Policy by Alan Burchill
If you want to use my tests code you can connect to my Github: Basic Ansible playbooks for Windows.
Using Ansible like library programming in Python
Ansible is a very powerful tool. Using playbooks, something like a cookbook, is very easy to automate maintenance tasks of systems. I used Puppet and other tools like that but IMHO Ansible is the best one.
In some cases you need to manage dynamic systems and take into advantage of Ansible like a Python library is a very good complement for your scripts. This is my last requirement and because of that I decided to share some simple Python snippets that help you to understand how to use Ansible as a Python library.
Firstly an example about how to call an Ansible module with just one host in the inventory (test_modules.py):
#!/usr/bin/python import ansible.runner import ansible.playbook import ansible.inventory from ansible import callbacks from ansible import utils import json # the fastest way to set up the inventory # hosts list hosts = ["10.11.12.66"] # set up the inventory, if no group is defined then 'all' group is used by default example_inventory = ansible.inventory.Inventory(hosts) pm = ansible.runner.Runner( module_name = 'command', module_args = 'uname -a', timeout = 5, inventory = example_inventory, subset = 'all' # name of the hosts group ) out = pm.run() print json.dumps(out, sort_keys=True, indent=4, separators=(',', ': '))
As a second example, we’re going to use a simple Ansible Playbook with that code (test.yml):
- hosts: sample_group_name tasks: - name: just an uname command: uname -a
The Python code which uses that playbook is (test_playbook.py):
#!/usr/bin/python import ansible.runner import ansible.playbook import ansible.inventory from ansible import callbacks from ansible import utils import json ### setting up the inventory ## first of all, set up a host (or more) example_host = ansible.inventory.host.Host( name = '10.11.12.66', port = 22 ) # with its variables to modify the playbook example_host.set_variable( 'var', 'foo') ## secondly set up the group where the host(s) has to be added example_group = ansible.inventory.group.Group( name = 'sample_group_name' ) example_group.add_host(example_host) ## the last step is set up the invetory itself example_inventory = ansible.inventory.Inventory() example_inventory.add_group(example_group) example_inventory.subset('sample_group_name') # setting callbacks stats = callbacks.AggregateStats() playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY) runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY) # creating the playbook instance to run, based on "test.yml" file pb = ansible.playbook.PlayBook( playbook = "test.yml", stats = stats, callbacks = playbook_cb, runner_callbacks = runner_cb, inventory = example_inventory, check=True ) # running the playbook pr = pb.run() # print the summary of results for each host print json.dumps(pr, sort_keys=True, indent=4, separators=(',', ': '))
If you want to download example files you can go to my github account: github.com/oriolrius/programming-ansible-basics
I hope it was useful for you.