How Do You Get Past “ImportError: No module named ‘boto'”?

Problem scenario
You want to retrieve VPC peering connection info and other VPC info via Boto3. With Python 3 you tried to run this Python 2 (and Boto 2.x) program:

import boto.vpc
c = boto.vpc.connect_to_region('us-east-1')
vpcs = c.get_all_vpcs()
vpc_peering_connection = c.create_vpc_peering_connection(vpcs[0].id, vpcs[1].id)

(It was written by the person who developed Boto 2.x here.)

You have a variety or problems with the syntax not working. Here are some example error messages:

ImportError: No module named 'boto'

NameError: name 'boto' is not defined

NameError: name 'vpc' is not defined

What do you do to adapt "import boto.vpc" and using Boto3 to interact with VPC components (with Python 3) or otherwise get the above program to work?

Solution
Try this program (but replace "pcx-abcd1234" with a VpcPeeringConnection ID):

import boto3
ec2_contint = boto3.client('ec2')
pcs = ec2_contint.describe_vpc_peering_connections(VpcPeeringConnectionsIds=['pcx-abcd1234'])
#to list all peering connections uncomment out this line:
#pcs = ec2_contint.describe_vpc_peering_connections()
print(pcs)

How Do You Create a Function in JavaScript?

Problem scenario
You want to create a function in JavaScript. This way you can use code over-and-over. How do you use a function in JavaScript?

Solution
Call this file contint.html

<!DOCTYPE html>
<html>
<body>

<h2>This demonstrates accepting input and using a function in JavaScript</h2>


<p id="demo"></p>

<script>

x = 5
var foo = prompt("Please enter a number");

function contintFunction(p1, p2) {
  return p1 * p2;   // The function returns the product of p1 and p2
}

last = contintFunction(x, foo)
alert(last)

</script> 

</body>
</html>

How Do You Cancel a Postfix Mail Queue?

Problem scneario
You use the mailq command. You see several emails have timed out. These emails are essentially in an "outbox" and a future delivery attempt is in the near future. How do you cancel the sending of these emails?

Solution
If you use the mailq command, each email will have a queue ID. It will be an alphanumeric value on the left hand column. To delete an email, first find its queue ID with the mailq command. Then issue this command constructed as such:

postsuper -d

Example:

sudo postsuper -d A971545854

To delete every message in the mail queue, run this:

sudo postsuper -d ALL

How Do You Get Nginx Logs to be in JSON format?

Problem scenario
The book Expert Python Programming (page 278) says 12 Factor app recommends that the application should not be aware of the format of the logs. JSON format for logs can be beneficial for various purposes. You want Nginx's access logs -- but not error logs -- to be in JSON format. What do you do?

Solution
Use a file like this for your nginx.conf. The only lines that are relevant are those from log_format json_combined escape=json to access_log /var/log/nginx/access.log json_combined; This sequence of lines, inclusive, makes the logging happen in a JSON format. The changes to this file do not take effect until you restart nginx, e.g., with this command sudo systemctl restart nginx.

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log debug;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  json_combined escape=json
                      '"time_local":"$time_local", '
                      '"remote_addr":"$remote_addr", '
                      '"remote_user":"$remote_user", '
                      '"request":"$request", '
                      '"status": "$status", '
                      '"body_bytes_sent":"$body_bytes_sent", '
                      '"request_time":"$request_time", '
                      '"http_referrer":"$http_referer", '
                      '"http_user_agent":"$http_user_agent", ';

    access_log  /var/log/nginx/access.log json_combined;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers PROFILE=SYSTEM;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

What are SLIs and SLOs?

Question
What does SLI and SLO stand for?

Answer
SLI is an initialism for Service Level Indicator. SLO is an initialism for Service Level Objective.

A Service Level Indicator is a metric of service such as query-per-second, megabytes per second, transactions per minute, HTTP requests per minute etc. These are quantifiable measurements of some I.T. service. SLIs, among other things, are the metrics of a monitoring system.

A Service Level Objective is a goal to facilitate a Service Level Indicator at a specified level. SLOs are closely related to the alerting thresholds in monitoring systems. The responding team will need time to react to an outage or near outage. An SLO usually connotes internal to the I.T. service provider. A managed service provider hosting a website or database would have an SLO with its staff that would be greater than the minimum associated with a Service Level Agreement.

A Service Level Agreement is an agreed upon (either contractually or through informal communications) that an I.T. company or group will maintain a minimum SLO. Should the provider fail to maintain a minimum SLO, the recourse would be a partial or complete refund of the money it received in consideration for accepting the contract.

To learn more about SLIs, SLOs, and SLAs, see these links:


To learn about tail latency, see this posting.

How Do You Configure the Wireless Security Camera with a TCP/IP Network?

Problem scenario
You have a camera (e.g., a TCP/IP ADT security camera) attached to your a router on the network with your laptop. You know the camera's MAC address by looking at the back of the camera itself (or you know its IP address on your network which is even more helpful). How do you use this camera over the network?

Solution
1. If you know the IP address of the camera skip to step #3. Otherwise, find the MAC address. It is usually on the back of the physical camera or possibly with the paperwork that came with the camera.

Mentally change the MAC address to this format: b8-e2-38-a7-1d-21

There must by hyphens in-between every two characters. There must be no colons.

2. Open a PowerShell window. Run this command, but substitute b8-e2-38-a7-1d-21 with the MAC

arp -a | select-string "b8-e2-38-a7-1d-21" |% { $_.ToString().Trim().Split(" ")[0] }

This should give you the IP address.

3. You can construct useful URLs like this as a test: http://x.x.x.x/img/snapshot.cgi?size=3
(Where x.x.x.x is the IP address of the camera.)

4. If you want to administer the camera (and do more than capture still photos with it), open a web browser and go to the IP address.

If you know the camera's username and password, skip this step. Try "administrator" with no password if you do not know. If that doesn't work, make sure that the camera is not connected to a network with the internet. Hold the reset button for 10 seconds. When the device is ready again, try credentials for "administrator" with a blank password.

Resetting the device when it is attached to the internet seems to allow the device to get its password reset from ADT's network on the internet. This is true even if you have no active subscription with ADT.

5. Now you can log in and administer the device. Just open a web browser and go to http://x.x.x.x where x.x.x.x is its IP address. Click on "Administration."

6. You are now done. The next two steps allow you to automate the uploading of images captured by the camera to Amazon's S3. The next two steps require s3cmd to be installed and for you to have an AWS account. Create a Python program like this. (This is Python 2. You may want to re-rewrite it in Python 3 now that it is 2019.)

# s3backupb.py has the following lines (but replace 192.168.1.6 with the IP address of the camera)
import time
from time import gmtime, strftime
from subprocess import check_output
part1 = "curl http://192.168.1.6/img/snapshot.cgi?size=3 > /media/pi/Lexar/pres3/"


filename = strftime("%a:%d:%b:%Y:%H:%M:%S", gmtime()) + '.jpg'
command = part1 + filename

dwldpic = check_output(command, shell=True).split()

precom = "s3cmd -c /home/pi/.s3cfg put /media/pi/Lexar/pres3/"

midpart = " s3://foobarbucket/"
comm2 = precom + filename + midpart + filename
print "wait for 12 seconds"
time.sleep(12) # pause for 12 seconds

print "continue"
s3upload = check_output(comm2, shell=True).split()

7. Modify the crontab to have a stanza to run the Python program every minute. The results of crontab -l should look like this:

*   *   *   *   *    /usr/bin/python /home/pi/test/s3backupb.py

How Do You Find the Web UI of a GitLab Server on Your Network?

Problem scenario
You inherited a GitLab server on your network to manage. You want to find the front end of the URL. What should you do?

Solution
Find the external IP address. Log into the back-end. If it has access to the internet, run this command: curl icanhazip.com

If you have no access to the internet, run this command: ip addr show

Use the IP addresses exhaustively in a web browser with a port in this fashion (where ppp should be replaced with the port number you want to try): http://x.x.x.x:pppp

The port number may be one to five numbers long. To find the potential port, use this command:

sudo netstat -anlp | grep -i listen | grep nginx

Try the port numbers you see (but not their IP addresses, e.g., "0.0.0.0").

So if the external IP address of the GitLab server, as determined by the curl icanhazip.com, is 1.2.3.4, and the netstat command above returned "0.0.0.0:444" (among other output), construct this as the URL:

http://1.2.3.4:444

#The port above is obtained from the netstat command. The IP address above is obtained from the curl command.

What Type of Linux File Has Permissions That Are Symbolized with a “c”?

Problem scenario
You run this command: sudo ls -lh /dev

You see output like this:

crw-rw---- 1 root tty       7, 131 Dec 23 19:20 vcsa3
crw-rw---- 1 root tty       7, 132 Dec 23 19:20 vcsa4
crw-rw---- 1 root tty       7, 133 Dec 23 19:20 vcsa5
crw-rw---- 1 root tty       7, 134 Dec 23 19:20 vcsa6

You want to know if the "c" is a link to another file or something else. What type of file does the letter "c" designate?

Solution
It is a reference to a character device.

If you want to learn more, see this.

How Do You Get Molecule Commands to Work when You Get “Unable to contact the Docker daemon”?

Problem scenario
When in virtualenv you try to run a Molecule command. But you get this message:

ERROR: Unable to contact the Docker daemon. Please refer to https://docs.docker.com/config/daemon/ for managing the daemon

What should you do?

Solution
1. Exit virtualenv. Run this command: deactivate

2. Go back into virtualenv (e.g., run a command like this source my_env/bin/activate).

3. The problem should be gone by now. If you get the problem again, reboot the server.