Aggcat Python client for Intuit

I have a little budgeting side project that I am making into a product. Currently, I export my bank data via CSV and then import it into my tool. Tedious, but it works. I discovered two companies that own the financial institution aggregation space, Yodlee and Intuit.

Yodlee seems to own majority of the space but the documentation and examples were difficult. I'm hopeful this will change soon. After all, they are significantly cheaper once your application goes to production and they have an accelerator for startups. Very sweet!

On the other hand we have Intuit, the 800-lb gorilla. You probably know about Quickbooks, Turbo Tax, and Mint right? Yeah that's them, and they released a full REST api service to boot. They have nice documentation for developers and seem to be established with 18000+ institutions you can get data from.

I decided to make a rest client for Intuit's customer data API. It's called python-aggcat and you can get python-aggcat from the cheese shop as well. To install it just do the song and dance:

$ pip install python-aggcat

Then, read the python-aggcat docs. Now you can get all of your financial data via a pythonic API client. Enjoy! :)

Remove RSA Host Key

When you are SSHing into virtual machines on a daily basis this message tends to get annoying:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The RSA host key for XXX has changed,
and the key for the corresponding IP address XXX.XXX.XXX.XXX
is unknown. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
XXXX.
Please contact your system administrator.
Add correct host key in /Users/XXXX/.ssh/known_hosts to get rid of this message.
Offending key in /Users/XXXX/.ssh/known_hosts:28
RSA host key for XXXXXX has changed and you have requested strict checking.
Host key verification failed.

YUCK! You might get tired of editing the ssh known_hosts file and removing the offending line, but there is an easier way. Use ssh-keygen. If you know the host is bobby.example.com then just run

$ ssh-keygen -R bobby.example.com

And you're done!

Automate the non-automated with expect and Chef

Some of you may have already used expect in linux. It's a nifty little tool. A tool that allows you to automate command line interfaces that require interactive prompts. It's simple, let's look at an example of expect in action.

#!/usr/bin/expect -f

# Change your own password automatically
spawn passwd
expect "Enter new UNIX password: "
send "mynewpassword\r"
expect "Retype new UNIX password: "
send "mynewpassword\r"
expect eof

Notice the shebang line #!/usr/bin/expect -f. Expect is an interactive shell. If you just type expect from the command line you will be placed in a shell that gives you commands such as spawn, send, and expect.

Let's look at what expect is doing in the code snippet above.


We tell expect to spawn a child process of passwd

spawn passwd

Next, we tell expect to wait for some stout from the child process where the text says Enter New UNIX password

expect "Enter new UNIX password: "

Then we tell expect to send a password with a carriage return, the \r idiom.

send "mynewpassword\r"

Finally, we expect the termination of the child process.

expect eof


So, how do we implement this in Chef? It's more simple than you think.

bash "modify_root_password" do
    user "root"
    code <<-EOF
    /usr/bin/expect -c 'spawn passwd
    expect "Enter new UNIX password: "
    send "#{user_root['password']}\r"
    expect "Retype new UNIX password: "
    send "#{user_root['password']}\r"
    expect eof'
    EOF
end

You're done! It's similar to the code with a few exceptions:

  • It's wrapped in Chefs bash resource and using the attribute code to tell it what to execute. The user_root hash comes from an encrypted data bag.

  • We use the '/usr/bin/expect -c' notation because as far as i know chef doesnt implement an expect interpreter under the script resource.


Here is another example creating a tarsnap keyfile:

bash "create_tarsnap_private_key" do
    not_if do
        File.exists?("#{node[:tarsnap][:private_key]}")
    end
    user "root"
    cwd "/tmp"
    code <<-EOF
    /usr/bin/expect -c 'spawn tarsnap-keygen --keyfile #{node[:tarsnap][:private_key]} --machine #{node[:fqdn]}  --user #{tarsnap_user['username']}
    expect "Enter tarsnap account password: "
    send "#{tarsnap_user['password']}\r"
    expect eof'
    EOF
end

I have made a cookbook that automates the tarsnap install process for you.

GitHub – glenbot

Glen Zangirolami

Houston, TX

Python Developer