fax cover sheet tool - this yak needs a SHAVE

From the point of view of 2016, faxing something seems almost quaint. But, the realities of business being what they are, people still need to fax things sometimes. My alter-ego at Custom Insurance Services has a little problem...

We have been maintaining a Hylafax server, with a POTS line and an external modem and everything, for about 12 years since we retired the last standalone fax machine in the office. We have long since switched to a hosted service for receiving incoming faxes, but we still maintain that Hylafax box for outgoing faxes at the moment.

I would like to retire that box. Hylafax itself is rock solid, but the client software we need to use to access it -- we've been using YajHFC, Yet Another Java Hylafax Client -- is kind of buggy and weird. It's a pain to update the cover page on Hylafax because it requires manual editing of PostScript.

We have an outbound fax service that's now thrown in for free with our hosted voice telephone services, which is nice. The problem is that the tooling around it is somewhat lacking. For business purposes we need a nice cover sheet, we need a centralized record of what we sent, etc. The free service is basically an email address. If you send from the right source address, it pulls the destination number out of the subject line and sends whatever content it finds in PDF attachments.

So, what I need is an easy tool for users to interact with this service. What I was thinking is:

  • A nice looking, mobile-friendly web app
  • Accessible outside our LAN (e.g. secure enough to expose through the firewall)
  • Login required, preferably tied to our Active Directory server or our Google Apps for Work accounts
  • Per-user preferences for things like sender name, title, voice number.
  • For each fax send, it should ask the destination name, title, company, destination fax number, a short subject line and potentially a longer bit of text.
  • That info should be used to populate a template cover sheet. The template should be easy for a competent programmer to edit, if not editable by just anyone off the street. (It should not require a hex editor to get the template right.)
  • It should allow uploading of multiple content files, adjustment of the order of those files if needed, and validating each content file to make sure it's valid readable PDF.
  • It should insert the total page count on to the cover sheet once all the content is concatenated.
  • It should drop that merged file into a database along with indexing information and a timestamp.
  • It should email the content over to our SMTP-based fax sending service. (Ideally it should impersonate sending from the logged-in user so success/failure notifications go to the right place.)

A web app that does this wouldn't be that hard to build.  It might be easier to build my own than to find one that already does this. Using tools I already know, I would probably build the UI using Django and its HTML forms tools, use PDFTK command lines for the PDF manipulation and metadata reading, and ReportLab for generating the cover sheet. For isolation and fault tolerance I would run this on our in-house Kubernetes cluster and expose it via a high port.

Posting this just in case someone happens to know of something like this that already exists, or in case someone has an interest in using what I end up building.

 

 

You can't get there from here: solving kubernetes flannel configuration issues

After following the Kubernetes (K8) Documentation for installing K8 on bare-metal Ubuntu nodes, I encountered some difficulties getting Services to work properly, and getting containers on different nodes to see each other.

With the help of Justin Santa Barbara <https://twitter.com/justinsantab> in the K8 #kubernetes-users Slack channel, I was able to determine my flannel overlay network was misconfigured.  (Previously I had assumed it was working OK, because I could create and manage replication controllers, pods, etc. with no problems.)

Basically, containers could see the Internet, but could not see each other unless two pods happened to land on the same node.  Services created via the K8 API were not network-visible outside the node either, whether inside or outside the cluster.

Solving the immediate problem

I'm not sure how that configuration got messed up, but I suspect it was when I installed the latest version of docker from the Docker-managed PPA .  In order to fix it, here's what I did:

  • I stopped all current replication controllers and my gluster volume. Just in case I screwed something up, I didn't want to accidentally create a split brain.
  • I stopped the flannel daemons on all nodes participating in the cluster.
  • I used /opt/bin/etcdctl to reconfigure the network range under the key "/coreos.com/network/config" -- specifying a range that did not conflict with existing private-addressing schemes on the LAN.
  • After taking note of how to restore the entries just in case, I used /opt/bin/etcdctl to delete all existing subnet leases.  After reading up on flannel a bit, the configuration is actually pretty simple. I would liken it to the way that DHCP assigns IPs from a range; flannel, communicating via etcd, assigns subnet ranges to participating nodes in the same way.  (I also tried to configure it for host-gw networking, since my flat layer 2 network should permit that, but I couldn't get it to work and switched back to vxlan, which seems to work fine.)
  • I restarted the flannel daemons on all hosts, making sure that /etc/default/flanneld contained correct etcd-endpoints and iface lines on all nodes.  (My bare-metal nodes have two ethernet adapters; I've configured the secondary adapter on each node to serve as an isolated network just for gluster nodes to talk to each other.)
  • I looked at /opt/bin/etcdctl ls /coreos.com/network/subnets to make sure the old subnet info hadn't re-created itself somehow, and to make sure that new leases were being assigned out of the newly configured range.
  • I noted the range assigned to each node, which you could tell by looking at the output of ifconfig and looking for the flannel.1 adapter.
  • Docker, running on each node, needs to use an IP from the node's assigned flannel subnet as its bridge address for docker0.  Flannel writes this info to /run/flannel/subnet.env but I couldn't figure out how to get the docker daemon (in the amount of time I had) to read those values. Apparently whatever startup process that reads /etc/default/docker does not evaluate that file as shell -- I couldn't get it to expand the environment variables.  But, since I knew the subnet range assigned to each node, I just configured the --bip parameter for each node by hand. (This is a very small cluster and this method obviously would not work for anything more than a few nodes.)
  • I restarted the docker daemon on each node so it would pick up the new configuration, and confirmed that the correct docker0 address had been assigned through ifconfig.  It was.
  • I spun up a container with an exposed port and confirmed that I could reach that port from another node in the cluster, and I could.  I created a type:NodePort k8 service entry to expose that port to the rest of the world, and that worked also.  Finally I confirmed that I could reach the exposed service through any node in the cluster when connecting to the correct port.  Previously none of this had worked, but now it does.

  Here are the rc and service YML files I used: http://pastebin.com/d1J3H5xL

Takeaways

During this process, looking at the logs in /var/log/upstart/docker.log and /var/log/upstart/flanneld.log were invaluable.

It seems like there should be some kind of config lint tool for flannel/kubernetes installs that warn of problems like this ... until I poked around looking for the problem, I never got any messages that anything was wrong! Automated installs are great but if you don't understand what they are doing under the hood, and they get messed up, they are tough to debug.

Solve the world's greatest mystery: Where Did All the Humans Go?

I started thinking about this as a joke.

But the more I think about it, the more I think that it must be done.

Thus I bring to you... Mountain Goat from Fort Pedro Informatics' game division.

"Mountain Goat Mount Massive" by Darklich14. Licensed under CC BY 3.0 via Wikimedia Commons

"Mountain Goat Mount Massive" by Darklich14. Licensed under CC BY 3.0 via Wikimedia Commons