Design Principles for “Project Ash”

Project Ash: PHP Wrappers for Tucows APIs

Work on Project Ash, my project to develop PHP libraries to access the Tucows APIs, is progressing and picking up speed. While working on it, I thought I'd share my general design principles for Project Ash with you…

Compatibility with both PHP 4 and 5.

This is an important stipulation: a number of our partners are sticking with PHP 4 so as not to break PHP 4-based applications on which both they and their customers rely. Although I will be building the libraries in PHP 5 to take advantage of some development niceties such as the use of the PHPUnit unit testing framework, I'm targeting PHP 4. I'll write the code in such a way that it will run under PHP 4 and will test on a PHP 4-equipped computer.

Input as Simple as Possible, But No Simpler

When you make API calls using the libraries, it should be a simple as calling a method or function and providing parameters through its arguments. For example, a call to the function that wraps the API call to the live server for the lookup domain for the domain example.com should look something like this:

$result = lookup_domain('live', 'example.com');

and not like this:

$params = array('server' => 'live',                'domain' => 'example.com');$result = lookup_domain($params);

Output as Simple as Possible, But No Simpler

Some of the Tucows APIs return large data structures which often contain redundant information, such as the way the XCP API returns both a numeric and text response code (the text response code is good for debugging, however). Some of these structures are deeply nested. The Ash libraries will be designed so that any output they produce will have no redundant information and will be as “shallow” as possible.

Plain Old Functions, When They Make Sense

Although the object-oriented programming is a great organizational technique for software, I'm don't think that it's the be-all and end-all of programming.

Consider the Lookup Domain API call, which accepts a domain name and returns a value that indicates whether it's available: for such a simple action, I don't think there's any need to instantiate a class just to make this call. Why not simply call a function called lookup_domain()?

Classes, When They Make Sense

Other calls, such as SW Register Domain require a lot of setup in the form of a large number of parameters, some parameters may depend on others and some business logic may be required. In such cases, using classes to manage the complexities of these API calls makes sense.

No “Magic Numbers”

Many Tucows API functions return numeric result codes. In order to reduce the likelihood of programming errors and help you make your client code more readable, the libraries will come with a large number of predefined constants for result codes so you won't have to memorize that 210 means “Domain available” and 211 means “Domain taken”.

A Step Towards a Mashable Future

Project Ash should be the first step towards a “mashable future” for the Tucows APIs, one in which it should be easy to a developer to incorporate Tucows services into his or her own applications. Rather than handing out large monolithic clients that are difficult to customize for your business, I'd like to see little pieces that are easy to plug into your existing and future projects.

Back from Vacation

Geek vacation
A geek going on vacation.

I'm back from a week-long vacation in the San Francisco Bay Area and am now working of turning a set of almost-complete articles for the Tucows Blog into complete ones! Watch this space for articles on:

  • Breaking away from Blogware's table-based layout, at long last
  • Progress on Project Ash
  • Announcements about Tucows services
  • Web industry news

How to Ace the Tucows Job Fair

Last weekend, we had a job fair here at Tucows. We hold job fairs at our Toronto headquarters every three or four months.

I spoke to Crystal McPhee who leads our recruiting to get some insider tips about how to make sure you make the best of a Tucows Job Fair. Here's the scoop:

1. Keeners come early. Arriving early in the day shows you're interested in the job.

2. Dress for success. Once you land the job with us, you get to work in a casual environment. However, first impressions count. So consider wearing business casual clothes to the job fair and not your favourite torn AC/DC t-shirt.

3. Be prepared. Bring a copy of your resume, a pen and a notebook. Brainstorm a list of questions and take notes.

4. Do your homework. Spend some time on our website and blog to learn about what we do and how we do it.

5. Be ready to answer questions and tell us why you want to work at Tucows. We'd like to hear the story of your career so far. You need to be able to tell us who you are, what you've done at previous jobs, how you work and why you'd be an asset to our team.

And there you have five easy tips to help you get the most from our job fairs.

We're always on the look-out for talented folks to join the herd. Click here to see a list of current job openings.

Taking Measures to Stop Spammers

One of our readers left us this comment last week:

“I’d be interested to know what (if any) measures you have in place to stop spammers registering their domains in the first place and/or detect spam registrations after the event.”

As your intrepid reporter, I spoke with Garrick Lau, who is driving forward several Abuse initiatives here at Tucows. Here is what I learned about how we’re stopping spammers:

Tucows has a dedicated Abuse team that monitors system logs, and abuse related activity across the our services. The Abuse team will actively disable offending spammers based on evidence found in system logs as well as complaints reported to our Customer Service team. At this time, this process is manual rather than automated.

We realize spamming and phishing are big problems. We’re in the early stages on projects to put more controls in place for automating our policy enforcement and monitoring across all our services.

Tucows is also involved in industry standards groups like MAAWG (Messaging Anti- Abuse Working Group) to learn what others in the industry are doing to control spam and related abuse and so we can share our own experiences.

To report a spamming or phishing domain to us, please send complete evidence of the offending domain and the content of the spam message with full headers to abuse@abuse.tucows.com.

Job Opportunity at Tucows: Network Engineer

Network Engineer

Here's another job opportunity at Tucows: Network Engineer!

About Tucows

For more about Tucows and its work environment, go check out the What Does Tucows Do, Anyway? and The Sort of Person We're Lookng For sections of this blog entry.

Main purpose

As a member of the Networking team, the Network Engineer is responsible for keeping all of Tucows' networks running smoothly so that their regularly scheduled operational, maintenance and support functions are carried out effectively and efficiently. It's a vital jobs — if our networks are out of business, so are we!

Position reports to: Operations Manager

Salary range: Commensurate with experience

Key responsibilities

  • Support, update and troubleshoot network hardware and software
  • Provide support on NOC and Service Desk issues
  • Perform network administration services, day-to-day operations
  • First line support of the network for Operations and Engineering implementations
  • Perform daily maintenance of the internal and production network, by checking all logs and ensuring no new issues are occurring
  • Monitor and resolve service desk tickets quickly
  • Perform emergency and planned maintenances in order to fix or prevent network outages
  • Work on infrastructure / network related projects such as:
    • Software and hardware upgrades
    • Network expansion
    • Deployment of network applications
    The products include, but are not limited to:
    • Core Switches
    • Distribution Switches
    • Firewalls
    • VPN Appliances
    • Content Switches
    • IPS / IDS's and Sniffers

Ideal Candidate Profile

Related experience / Unique skill set

  • At least 2 years work experience as Network Administrator in a medium size network.
  • Demonstrated abilities with, and a good working knowledge of:
    • General networking
    • Ethernet
    • TCP/IP
    • DNS
    • DHCP
    • Switching
    • Routing
    • IP Addressing / sub-netting
    • Windows networking
  • Excellent communication (written and verbal) and interpersonal skills
  • Experience configuring, upgrading and maintaining Cisco switches and routers; hands on required on Catalyst 6500
  • Experience configuring, upgrading and maintaining:
    • Cisco PIX
    • Cisco VPN3000
    • Cisco CSS11500
    • Cisco FWSW
    • Cisco IDS/IPS
    • Netscreen firewalls
  • Basic Unix administration skills, knowledge of open source network tools an asset
  • Experience or exposure in configuring and troubleshooting routing protocols OSPF, BGP

Education

  • Bachelor Degree in Computer Science
  • CCNA / CCNP

Interpersonal skills

  • Excellent organization and time management skills to meet demanding timelines
  • Strong interpersonal and customer service skills
  • Excellent verbal and written communication skills
  • Highly adaptable with ability to work independently and collaboratively in a fast paced, demanding environment
  • Must be highly adaptable and able to learn new applications quickly
  • Self-motivated, with strong sense of ownership and urgency to deliver projects / tasks in a timely fashion
  • Attention to detail required, must be methodical and thorough in problem solving

Other

  • Position requires to carry a pager on alternate basis
  • Overtime may be required during project implementation

Interested in this job?

If this job sounds like the sort of thing you'd be interested in doing, send your resume and cover letter to hrdept@tucows.com, and make sure you put Network Engineer in the subject line!

Tucows Job Fair Tomorrow!

Squishy Cows on a Mac PowerBook

Job Fair!

Tomorrow, Saturday, February 10th, from 9:30 a.m. to 12:30 p.m., Tucows is having a job fair! We've got openings for the following positions:

“Tucows? You Mean the Shareware Company?”

If you're thinking “Tucows? You mean the shareware company?”, make sure you read about the sort of business we're in. There's a good summary in this article; make a note of the What Does Tucows Do, Anyway? and the The Sort of Person We're Lookng For sections.

What Happens at the Job Fair

At tomorrow's job fair, you'll get to meet one-on-one with actual managers. The managers are people with hiring authority for the open positions; you'll have a brief interview with them where you can talk about your skills and experience and ask questions about Tucows. Successful candidates from tomorrow's interviews will be invited to come back for a more in-depth interview on the week of February 12th.

What to Bring and Where to Go

If you'd like to attend tomorrow's job fair, bring your resume and your “'A' game” to the Tucows offices, located at 96 Mowat Avenue, Toronto (Mowat is a block east of King and Dufferin — you can get here via the Dufferin 29 bus or the King 504 Streetcar; there's plenty of nearby parking too). Each interview is expected to last about 15 minutes, but you should be prepared to spend an hour here to allow for some administrivia and waiting for your interview to come up.

Job Opportunity at Tucows: Senior Application Developer

Senior Application Developer

Are you a programmer looking for work? Here at Tucows, we've got another job opening: Senior Application Developer.

What Does Tucows Do, Anyway?

If you're interested in this sort of job, you might want to know the sort of business we're in. Simply put, Tucows is a wholesaler of these specific internet services:

  • Domain names
  • Hosted email
  • Hosted anti-spam solutions
  • Digital certificates
  • Managed DNS
  • Website Builder
  • Blogware
  • Billing software for ISPs and hosting services

As a wholesaler, we don't directly sell these services to end-users. Rather, we partner with people — many of whom are ISPs and hosting companies — who then resell these services on their own or as part of their own suite of services. Our partners can provision these services to their customers either via a web-based interface or by using our APIs.

By buying these services from us and reselling them instead of setting up and maintaining these services themselves, our partners can worry less about the tech and maintenance aspects of these services and concentrate on provisioning them to their customers and providing them with great service.

The Sort of Person We're Lookng For

Make sure you read this article over at the blog Creating Passionate Users in which Kathy Sierra writes about companies where people are really into their jobs:

People ask me, “How can I get our employees to be passionate about the company?” Wrong question. Passion for our employer, manager, current job? Irrelevant. Passion for our profession and the kind of work we do? Crucial. If I own company FOO, I don't need employees with a passion for FOO. I want those with a passion for the work they're doing. The company should behave just like a good user interface — support people in doing what they're trying to do, and stay the hell out of their way. Applying the employer-as-UI model, the best company is one in which the employees are so engaged in their work that the company fades into the background.

That's been my experience here at Tucows: the company does a pretty good job at supporting people in their tasks, but also staying the hell out of their way and not binding them down with too many diktats. Do you prefer to work using editor X running on operating system Y? Do it; we don't mandate what's on your desktop. Got ideas on how to do things more effectively and efficiently? The folks here are pretty good at listening to them. Developers here are empowered to be creative while doing their job.

All that freedom means that we're looking for a developer who's a self-starter, capable of working with minimal supervision — or none at all.You'll be part of a team that will be both building new services as well as enhancing, maintaining and supporting existing ones. You also have to be a good team player, leader and teacher, as you may be involved with mentoring and helping junior members of the team.

The systems you'll be working on are big — we're talking millions of transactions a day, for which our customers and customers' customer have paid. In such an environment, anything that can go wrong will go wrong, so we're looking for someone who can crank out high quality code.

You have to be the kind of person who lives to work on challenging problems. There'll be a lot of ground to cover, and the industry changes pretty quickly, so you've got to be the sort of person who wants to learn as much as possible, as quickly as possible, while solving those problems. We're looking for someone who takes pride in their work and wants to be proudly describe the type of problems they're working on.

And Now, the Checklists!

Here's what's on the “key responsibilities” checklist of the job posting:

  • Design, development and maintenance of code
  • Strong code testing and refactoring skills
  • Review business and functional requirements
  • Production support activities including troubleshooting and resolving the problems
  • Assist in release management
  • Additional responsibilities as required

Here's the “skills and experience” checklist:

  • 5 Years development experience with:
    • Perl (Java and PHP are a bonus)
    • Client/server application development for a Unix/Linux platform
  • You should also have experience with:
    • Large scale projects
    • Object-oriented design and development (bonus marks for knowing your design patterns!)
    • Working with RDBMS systems, Oracle in particular as well as PostgreSQL and MySQL
    • Working with web applications and services
    • Writing shell scripts
    • Version control systems

Finally, the “soft skills” checklist:

  • Positive and constructive attitude
  • Demonstrated team player
  • Able to maintain a calm, professional approach when dealing with difficult customers
  • Attention to detail required, must be methodical and thorough in problem solving
  • Excellent planning and documentation skills
  • Excellent time management skills to meet demanding timelines
  • Excellent verbal and written communication skills
  • Highly adaptable with ability to work in a fast paced demanding environment
  • Must be able to own issues from inception to completion
  • Must be highly adaptable and able to learn new applications quickly
  • Must be team-oriented with ability to work well with multiple teams in a cross-functional setup
  • Self-motivated, with strong sense of ownership and urgency to deliver projects / tasks in a timely fashion
  • Responsible and accountable

Do You Want This Job?

If you'd like this job and think you can fill a Tucows Senior Dveeloper's shoes, we want to hear from you! Email your resume and cover letter to hrdept@tucows.com and refer to [Dev-2007-02-07-248] Senior Application Developer in the subject line.

Tucows Announces 4th Quarter Results / Conference Call Today at 5:00 p.m. EST

Cow on phone

I'm going to simply quote the official-sounding release:

Tucows Inc. (TSX: TC, AMEX: TCX) plans to release its fourth quarter fiscal 2006 financial results on Thursday, February 8, 2007, following market close. Company management will host a conference call on Thursday, February 8, 2007 at 5:00 p.m. EST (GMT -5) to discuss the results and outlook.

If you'd like to listen to the conference call, go to our Conference Call page and click on the “Click here to listen to the webcast” link. The link will be active about an hour prior to the call.

Yahoo! Pipes Explained

Yahoo! PipesPart of my job as Tucows' Technical Evangelist is to keep up with interesting developments in the programming world, and especially when those developments are around web programming. Today, it seems as though the tech blogopshere is abuzz with talk of Yahoo!'s new service, Pipes. I've written an explanation of the idea behind Pipes called Pipes Explained — it's in the tech blog I share with my buddy George called Global Nerdy. Check it out!

Project Ash: Writing a PHP Wrapper Library for the Tucows APIs

Project 'Ash': PHP Wrappers for Tucows APIs.

Welcome to the first report from Project Ash, my little project in which I plan to write PHP functions that will act as wrappers for Tucows API calls! As I write the library that will house these functions, I'll post reports from time to time that will apprise you of my progress, explain some of my design decisions and cover some details about the APIs that may not be covered in the official documentation.

What's the Goal of Project Ash?

The goal is to have a PHP 4/5 open source library of functions that allow you, as a developer, to worry less about the specifics of making calls to our APIs and concentrate on creating you application. With this library, it should be simple for someone with a Tucows API account (and some PHP programming skill, but not a lot) to write a PHP client that provisions Tucows services or to integrate Tucows service functions into existing PHP applications. Possible applications for such a library include:

  • Full-service provisioning sites: These are sites whose primary purpose is to provision and manage services such as domain names and email accounts. The library should make it much easier for you to build your own full-service client in PHP.
  • Sites that offer Tucows services as features: Perhaps you're running a dating site and would like to be able to offer your users an email mailbox that's separate from their regular email address. You can use the library to integrate email account provisioning and management with your service.
  • Offbeat apps and mash-ups: There are probably mash-up uses for the Tucows APIs I haven't yet thought up, but the Duke of URL application I wrote back in Dceember is an example of an offbeat app based on a single Tucows API call (the NAME_SUGGEST call).

By “Tucows APIs”, I refer to the three major APIs for the provisioning and management of Tucows services, which are listed below:

  • XCP: Also referred to as “the OpenSRS API”, this is our original API, made specifically for the provisioning and management of domain names. It dates back to when Tucows first got into the web service wholesale business, when domain names were the only service we offered. XCP is short for “eXternal Client Protocol”. You can download the latest documentation [PDF format] for XCP here.
  • TPP: The API for provisioning and managing services added after domain names, namely:
    • Digital Certificates
    • Email
    • Email Defense
    • Managed DNS
    • Website Builder
    TPP is short for “Tucows Provisioning Protocol”. You can download the basic TPP API docs [PDF format] here, and docs for specific TPP-based services can be found at here.
  • Blogware Reseller Provisioning API: Blogware, our own hosted blogging platform, has its own API (alas, it has no acronym – nobody calls it “BRPA”). The Blogware Reseller Provisioning API docs are available both online and in PDF format.

Chart: Which Tucows API?

In Project Ash, I'll first provide wrapper functions for XCP, then TPP, then BRPA — er, I mean the Blogware Reseller Provisioning API.

Why is the Project Named “Ash”?

The graphic accompanying this article should be a hint: it's named after the protagonist in Sam Raimi's Evil Dead series of horror movies. One tongue-in-cheek way of describing the character Ash is to say that he's “just one man with a chainsaw, trying to make a difference”. Ash's goals in swinging that chainsaw and mine in cobbling together this PHP library could be seen as similar, hence the project's name.

PHP OpenSRS Client: Project Ash's Foundation

I've made mention of the PHP OpenSRS Client project on SourceForge written by Colin Viebrock several times before. It will be the foundation on which the XCP and TPP parts of Ash will be built, as it takes care of two key operations:

  • Connecting to and authenticating with Tucows' servers
  • Sending and receiving messages to and from Tucows' servers

With these tasks out of the way, the Ash library is left to concentrate on providing functions that assemble the data structures that the PHP OpenSRS Client can easily convert into the XML that makes up XCP and TPP calls. In the next few sections, we'll take a look at building such a function.

First Steps: Anatomy of an XCP API Call

An XCP call can be viewed as an associative array (or, if you prefer, “hash” or “dictionary”) of parameters, which the documentation calls the input parameters. The input parameters contain details about the call itself, such as the name of the call and the object on which the call is to be performed. One of these input parameters is called attributes — this parameter is an associative array containing what we would consider to be the arguments of the call; the arguments to the wrapper functions will mostly be put into this array.

Diagram showing the structure of an XCP call.

Building the “Lookup Domain” Call

Let's see how this structure applies to one of the simplest XCP calls: Lookup Domain. If you'd like to see how it appears in the documentation, it's on page 194 of the 2.9.6 version of the OpenSRS API Specification [PDF link] (a.k.a. the XCP documentation). Given a domain name, this call returns a value that states whether or not it is available.

The table below shows how the call is structured:

Input parameter name Value
action

The action to be performed.

In the case of Lookup Domain, set this value to lookup or LOOKUP — it's not case-sensitive.

object

The object on which the action is to be performed.

In the case of Lookup Domain, set this value to domain or DOMAIN — it's not case-sensitive.

registrant_ip Optional. The IP address of the registrant, in “dotted quad” format (for example, 127.0.0.1).
attributes
Attribute name Value
domain Set this to the name of the domain for which you wish to perform the lookup.

On page 195 of the documentation, there's a Perl example of an associative array that defines a Lookup Domain call for the domain name example.com. Here it is:

{  
  protocol => 'XCP',  
  action => 'lookup',  
  object => 'domain',  
  registrant_ip => '111.121.121.121',  
  attributes => {  
    domain => 'example.com' 
} 

Let's translate this into PHP. It's easy — the Perl code above is simply an associative array literal. In PHP, array literals are a little bit more verbose since they include the keyword array (that's right, array isn't considered a function!). Here's the Perl array declaration translated into its PHP equivalent:

array(
    'action'        => 'lookup',
    'object'        => 'domain',
    'registrant_ip' => '111.121.121.121', 
    'attributes'    => array(
                         'domain' => 'example.com'
                       )
);

(Yes, I've skipped the 'protocol' => 'XCP' key-value pair — the PHP OpenSRS library lets us specify the protocol elsewhere.)

Now that we've built the API call, let's send it!

Sending the “Lookup Domain” Call

This is where the PHP OpenSRS Client comes in. Once you've built the associative array for the API call you want to use, you simply use the client to create an instance of an “OpenSRS” class and use that instance's send_cmd method to send the message to the Tucows servers. The class will handle all the details of authenticating, converting the associative array into XML that the Tucows servers can understand and sending the XML to the Tucows servers. The return value of send_cmd message will contain the servers' response.

Installing the PHP OpenSRS Client

If you haven't installed the PHP OpenSRS Client code yet, you might want to consult the Introducing OpenSRS-PHP article.

Enough preamble! Here's the complete code for a simple PHP script that makes a Lookup Domain API call based on associative array we created earlier:

<?php
require_once 'openSRS.php';
$server = new openSRS('LIVE', 'XCP');    
$cmd = array(
    'action'     => 'lookup',
    'object'     => 'domain',
    'registrant_ip' => '111.121.121.121', 
    'attributes' => array(
        'domain' => 'example.com'
    )
);
$result = $server->send_cmd($cmd);
echo("<h1>Lookup Results</h1>");
print_r($result);
?>

Assuming that all is well — your internet connection is working and you've defined your username and private keys in openSRS.php — when you run this script, you should get a page with a big headline that reads “Lookup Result” followed by:

Array ( [is_success] => 1 [response_code] => 211 [response_text] => Domain taken [attributes] => Array ( [status] => taken [upg_to_subdomain] => [reason] => ) )

It's time to look at the structure of the response.

Anatomy of an XCP Response

Like an XCP call, an XCP reponse can also be viewed as an associative array of parameters. The response parameters contain details about the call itself, such as whether the call was successfully performed and the result code for the call. The XCP response also has a parameter called attributes; like the XCP call parameter with the same name, this parameter is an associative array containing additional result data for the call; it's used when the result code for the call doesn't provide enough information (for example, API calls that return lists of data would place those lists into the attributes parameter).

Diagram showing the structure of an XCP response.

The table below shows how the response is structured:

Response parameter name Value
is_success 1 if the API command was executed successfully, 0 otherwise
response_code

A numeric code representing the result of the API call.

In the case of Lookup Domain, the possible values are:

  • 210 - Domain available.
  • 211 - Domain taken.
  • 221 - Domain taken (a waiting registration exists in OpenSRS). Note that this is for asynchronous registries only.
  • 250 - Action submitted successfully for processing to asynchronous registry.
response_text

Text representing the result of the API call.

It's best to use this value for debugging purposes only. Your program logic should be based on the value of response_code (see above).

attributes
Attribute name Value
status [available if the domain name is available, taken otherwise.]
upg_to_subdomain [Not covered in the docs; I'm going to bug someone about this.]
reason [Not covered in the docs; I'm going to bug someone about this.]

Using the XCP Response

In the case of Lookup Domain, looking at the is_success and response_code response parameters should be enough to determine:

  • Whether the call was successfully completed
  • Whether the given domain name is available

Other calls may return more complex results and may require looking at the values within the attributes parameter.

Building the Ash Library

The Ash library will encapsulate the PHP code to assemble API commands and send them to the Tucows servers into functions, with one function per API call. Instead of having to write all the PHP code, shown above, you should only have to write a single line of code like the only below to run the Lookup Domain command on the live server:

$result = lookupDomain('live', 'example.com');

And that's my goal. Over the next little while, I'm going to write functions to wrap each API call, starting with the XCP calls. Every now and again, I'll post an article here, covering my progress and reporting on little-known features of some of the API calls. Watch this space!

As always, if you have any questions or suggestions or would like to voice an opinion, let me know in the comments!