When You Have to Seek Truth in the Code

When Documenation is Misleading

Have you ever doubted documentation? Have you ever dug into the code and found that the documentation is misleading?

If the answer to any of the questions is yes, you have come to the right place.

Please do not get me wrong, I love documentation. I actually learn a lot through documentation and solve issues by following documentation. Maintaining accurate, readable, and up-to-date documentation is not an easy thing. We tend to improve our tools/software faster than documentation. Additionally, sometimes people who write the documentation are not the same people who develop the toolset. Messages may get lost during this process. How to write and maintain good up-to-date documentation is a whole different topic. In this blog, we focus on how to find out the truth beneath the not-so-accurate/confusing documentation.

Peeling Onions Layer by Layer

I call this approach “Peeling onions layer by layer”, the common thing here is that you will likely have tears. I will use a simplified real case from our work as an example to go through how this method works.

One of our clients asked us a question: “which port does BOSH vSphere CPI use to talk to vCenter, 80 or 443?” You could go and capture network traffic if you have access, but in our case, we were expected to find out the truth through documentation and code.

We peeled three layers Documentation => configs => source code and found the truth at the code core.

A quick search got us here from the documentation, we saw:

The vSphere CPI requires access to port 80/443 for all the ESXi hosts in your vSphere resource pool(s)

This is helpful, yet we still did not know which port was being used exactly. Next, we needed to take a look at the configs to see which port was configured to be used.

From more documentation, we found an example of CPI config. Unfortunately, it does not have a field to let you config port.

- name: ((vcenter_identifier))
  type: vsphere
    host: ((vcenter_ip))
    user: ((vcenter_user))
    password: ((vcenter_password))
    - clusters:
      - { ((vcenter_cluster)): {}}
      datastore_pattern: ((vcenter_datastores_pattern))
      disk_path: ((folder_to_put_disks_in))
      name: ((vcenter_datacenter))
      persistent_datastore_pattern: ((vcenter_persistent_datastores_pattern))
      template_folder: ((folder_to_put_templates_in))
      vm_folder: ((folder_to_put_vms_in))

Double-checking the spec file in case the port was being set using a default value. We found it was not set as the example above. We also did not find the port being listed as a configurable spec.

From the job template, we found that the port never gets passed in.

params = {
    "cloud" => {
      "plugin" => "vsphere",
      "properties" => {
        "vcenters" => [
            "host" => vcenter_host,
            "user" => p('vcenter.user'),
            "password" => p('vcenter.password'),
            "datacenters" => [],
            "default_disk_type" => p('vcenter.default_disk_type'),
            "enable_auto_anti_affinity_drs_rules" => p('vcenter.enable_auto_anti_affinity_drs_rules'),
            "upgrade_hw_version" => p('vcenter.upgrade_hw_version'),
            "enable_human_readable_name" => p('vcenter.enable_human_readable_name'),
            "http_logging" => p('vcenter.http_logging')
        "agent" => {
          "ntp" => p('ntp')

Since it did not support configuring the port, we needed to find out what port value was set as default in the code. We believe it should be 443, however, we dug into the code to verify our assumption.

From the Gemfile in the source code, we can see how the http(s) request is created here, and how the port is set to 443 as default here.

That was such a fun experience!


Thank you for reading my blog, I hope you enjoyed it.

Great appreciation goes to @jdee, this blog is inspired by watching him how to figure out the problem we described in this post.

Spread the word

twitter icon facebook icon linkedin icon