Zenoss 3.2 Email Alerts

After finding a bunch of Zenos 4 documents on the ‘Trigger’ tab, I became frustrated that I couldn’t find how to send email alerts in Zenos 3.2.  The Zenoss Core UI is extremely confusing.

Alerts can be created per user and per group.  Go to Advanced->Users->click user->Alerting Rules

Here you can create filters for events and get emailed about them.

JVM proxy through a remote/reverse SSH tunnel

You may come across a scenario where you need to test your Java application from an alternate network, or you may not have sufficient network access where your code/application resides.  The JVM comes equipped with awesome proxy capabilities using SOCKs and a more specific HTTP proxy.  These can be set as environment properties when starting the JVM (http.proxyHost,http.proxyPort,socksProxyHost,socksProxyPort) or set programatically.  You can even configure a ProxySelector class for advanced proxy logic.  See Oracle’s Documentation for advanced usage.

Your http requests can go through SOCKs as well, but if the HTTPProxy is defined, then it will use the more specific proxy for the protocol it needs.

Here’s an example of the JVM options you would use to start your Java application to use proxies:

-Xmx2G -Dhttp.proxyHost=192.168.1.2 -Dhttp.proxyPort=80 -DsocksProxyHost=192.168.1.2 -DsocksProxyPort=1080

But, what if you don’t have direct access to the proxy server? You’ll need to use an SSH Tunnel. What if you can’t SSH out of your box? If you can SSH in, you can still create a remote/reverse tunnel. Here’s how that is done in Putty. Right click on the top of your active ssh putty window and chose ‘Change Settings’. Add the tunnels shown in the screenshots below to your connection. I noticed that sometimes ssh servers don’t have permissions to open up lower-numbered ports, so it took some trial and error before discovering that higher-numbered ports worked. The destination address of the tunnel is where the port will be forwarded to. The ‘Dynamic’ setting turns the tunnel into a SOCKs proxy itself and may be good if you don’t have a SOCKs server available, but I never got this working, but could have been because I was trying lower port numbers.

Putty1

Putty2

After you add those ports and apply the settings to your putty ssh session, your development machine now has two listening ports, one for http proxy, one for SOCKs proxy. Then you point your JVM at the localhost ports rather than the remote proxy ports.

-Xmx2G -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8555 -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8666

The SOCKs proxy in the JVM will even tell MySQL database connections to use the proxy. If you want a specific Apache HttpClient connection to use the proxy, you can configure it like this:

DefaultHttpClient client = new DefaultHttpClient();
HttpHost proxy = new HttpHost(“127.0.0.1”, 8555, “http”);
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

or

client.getParams().setParameter(“socksProxyHost”,”127.0.0.1″);
client.getParams().setParameter(“socksProxyPort”, 8666);

If you are using Java’s URL class to make a request you can set a proxy for it:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(“127.0.0.1”, 8555));
HttpURLConnection connection = (HttpURLConnection) new
URL(myUrlString).openConnection(proxy);

If you are developing on a Windows box and need to SSH into that box, a good SSH Server that allows you to open up tunnels is COPSSH.

 

Adding a gmail alias for a forwarded google domains address

I decided to give domains.google.com a try and I like the email forwarding feature and the free private whois listing. After forwarding an email like admin@yournewfancydomain.com to your @gmail.com address, it isn’t straight forward to get gmail to add your forwarded email address as an alias so you can send from that address. I searched their docs and couldn’t find how to do this. Here’s the steps that Google Support provided to me to do it.

 

In Google Accounts:

  1. Go to Google Accounts

  2. Login using the recipient email address.

  3. Click the Security tab.

  4. Look for App passwords under the Password section. Note: The App Passwords option will only be visible if you have 2-Step Verification enabled.

  5. Click Settings under App passwords.

  6. Under Select app choose Mail.

  7. Under Select Device choose your respective device.

  8. Click Generate.

  9. Take note of the generated app password and just click Done.

 

In Gmail:

  1. Click the gear at the top right corner.

  2. Select Settings.

  3. Click Accounts and Import.

  4. Click Add another email address you own under Send mail as.

  5. Enter your alias email address then click Next Step. Keep the Treat as alias checked.

  6. Enter these values:

    • SMTP Server: smtp.gmail.com
    • Port: 465
    • Username: Your Gmail email address.
    • Password: The generated app password from Step 9.

        7.  Click Add Account.

        8.  Click the verification link sent to your Gmail.

It will then be possible to send using an alias. You may do a quick test by composing an email and choosing your email alias in the From field.

 

 

Thrive Life Pro is leaving Beta

It’s been exciting to get Thrive Life Pro to the point that we can leave beta. We have been able to acquire a lot of users that are excited to use it and improve their ability to manage their time in their Thrive Life businesses. Thrive Life Pro (TLPro) is a contact management system that allows Thrive Life consultants to assign tasks and associate them with events and contacts. It helps keep consultants organized and helps them communicate more effectively with their customers, downline, and prospects.

100% height div not working

Sometimes, even with a lot of tricky css, you still can’t get a div to stretch to the height of it’s parent. Sometimes this height is also determined by an adjacent table cell. In this case, JavaScript and jQuery come in handy.

        jQuery('.innerWrapper').css('height', 'auto');
        var maxHeight = 0;
        jQuery('td.outerCell').each(function() {
            var height = jQuery(this).outerHeight();
            if (height > maxHeight) {
                maxHeight = height;
            }
        });
        jQuery('.innerWrapper').css('height', maxHeight);

JSP Help Icon Tag

public class HelpIconTag extends TagSupport {
    
    private String key;
    public void setKey(String key) {
        this.key = key;
    }

    private String position = "";
    public void setPosition(String position) {
        this.position = position;
    }
    
    private int level = 1;
    public void setLevel(int level) {
        this.level = level;
    }
    
    @Override
    public int doStartTag() throws JspException {
        try {
            ServiceContainer services = (ServiceContainer) pageContext.getRequest().getAttribute(Key.SERVICES);
            TenantSettings settings = null;
            if(services.tenant != null ) {
                settings = services.tenant.getSettings();
            }
            if(settings == null || settings.getHelpId() == null || settings.getHelpId().intValue() <= level) {
                JspWriter out = pageContext.getOut();
                String helpString = services.cmsService.getHelp(key);
                if(helpString == null || helpString.isEmpty()) {
                    helpString = key + "Help";
                }
                out.print("");
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
        return SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }
}

jQuery Dialog Utility

Ever have a web interface that requires a lot of dialog popup windows?  I came up with this JavaScript utility class to help me create, show, and delete dialog boxes.  I also added a confirmation dialog box method and a simple message method.

var Dialog = {
    dialogId: 'dialogBox',
    createDialog: function(id, width, height) {
        jQuery('body').append("");
        var buttons = {};
        jQuery('#' + id).dialog({
            width: width,
            height: height,
            position: ['center', 50],
            autoOpen: false,
            resizable: false,
            modal: true,
            close: function(event, ui) {
                Dialog.closeDialog(id);
            },
            buttons: buttons
        });
    },
    closeDialog: function(id) {
        jQuery('#' + id).dialog('destroy');
        jQuery('#' + id).remove();
    },
    showConfirm: function(message, width, callback, callbackArgs) {
        if(!width) {
            width = 200;
        }
        // Setup Dialog Box
        jQuery('body').append("");
        jQuery('#' + Dialog.dialogId).dialog({
            width: width + 'px',
            autoOpen: false,
            resizable: false,
            hide: "fade",
            modal: true,
            close: function(event, ui) {
                jQuery('#' + Dialog.dialogId).dialog('destroy');
                jQuery('#' + Dialog.dialogId).remove();
            },
            buttons: {
                Cancel: function() {
                    jQuery(this).dialog("close");
                },
                Yes: function() {
                    callback(callbackArgs);
                    jQuery(this).dialog("close");
                }
            }
        });
        jQuery('#' + Dialog.dialogId).dialog('open');
    },
    showMessage: function(message, width, closeTime) {
        if(!width) {
            width = 400;
        }
        // Setup Dialog Box
        jQuery('body').append("");
        jQuery('#' + Dialog.dialogId).dialog({
            width: width + 'px',
            autoOpen: false,
            resizable: false,
            position: ['center', 300],
            hide: "fade",
            modal: true,
            close: function(event, ui) {
                jQuery('#' + Dialog.dialogId).dialog('destroy');
                jQuery('#' + Dialog.dialogId).remove();
            },
            buttons: {
                Ok: function() {
                    jQuery(this).dialog("close");
                }
            }
        });
        jQuery('#' + Dialog.dialogId).dialog('open');
        if(closeTime) {
            setTimeout("jQuery('#" + Dialog.dialogId + "').dialog('close')", closeTime);
        }
    }
};