net.networksaremadeofstring.cyllell.Cuts.java Source code

Java tutorial

Introduction

Here is the source code for net.networksaremadeofstring.cyllell.Cuts.java

Source

/*
* Copyright (C) 2011 - Gareth Llewellyn
*
* This file is part of Cyllell - http://blog.NetworksAreMadeOfString.co.uk/cyllell/
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>
*/
package net.networksaremadeofstring.cyllell;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/* A knife is used for cutting so that's what this little class does.
 * I'm tempted to make Cuts() used for GETs and Slash() used for POSTS but
 * we'll just have to wait and see
 */
public class Cuts {
    private SharedPreferences settings = null;
    private String ChefURL = "https://api.opscode.com"; //Hosted Chef
    private String PathSuffix = "/organizations/namos"; //Hosted Chef
    //private String UserID = "Cyllell"; //The name of the API client
    //private String PrivateKey = null;

    private ResponseHandler<String> responseHandler;
    //private String JSONReturn = "";
    private Authentication ChefAuth = null;

    //These don't get used directly
    private DefaultHttpClient client;
    private SingleClientConnManager mgr;

    //This one is the HttpClient we do use;
    private DefaultHttpClient httpClient;
    public HttpGet httpget = null;
    public HttpPut httpput = null;
    public HttpDelete httpdelete = null;

    public Cuts(Context thisContext) throws Exception {
        settings = thisContext.getSharedPreferences("Cyllell", 0);

        responseHandler = new BasicResponseHandler();

        if (settings.getString("URL", "--").equals("--") == false
                && settings.getString("ClientName", "--").equals("--") == false
                && settings.getString("PrivateKey", "--").equals("--") == false) {
            ChefAuth = new Authentication(settings.getString("ClientName", "--"),
                    settings.getString("PrivateKey", "--"));
            this.ChefURL = settings.getString("URL", "--");
            this.PathSuffix = settings.getString("Suffix", "");
        } else {
            //Log.i("URL",settings.getString("URL", "--"));
            //Log.i("ClientName",settings.getString("ClientName", "--"));
            //Log.i("PrivateKey",settings.getString("PrivateKey", "--"));
            throw new Exception("Chef URL is not set");
        }

        //Create the httpclient that trusts everything!
        this.PrepareSSLHTTPClient();
    }

    private void PrepareSSLHTTPClient()
            throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
        HttpParams httpParameters = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
        HttpConnectionParams.setSoTimeout(httpParameters, 5000);

        client = new DefaultHttpClient(httpParameters);

        SchemeRegistry registry = new SchemeRegistry();
        SocketFactory socketFactory = null;

        //Check whether people are self signing or not
        if (settings.getBoolean("SelfSigned", true)) {
            //Log.i("SelfSigned","Allowing Self Signed Certificates");
            socketFactory = TrustAllSSLSocketFactory.getDefault();
        } else {
            //Log.i("SelfSigned","Enforcing Certificate checks");
            socketFactory = SSLSocketFactory.getSocketFactory();
        }
        registry.register(new Scheme("https", socketFactory, 443));
        mgr = new SingleClientConnManager(client.getParams(), registry);

        httpClient = new DefaultHttpClient(mgr, client.getParams());
    }

    /**
     * Gets a list of all Nodes in the system along with the URI's to get additional details
     * @return - JSONObject - Returns a hash of uri's for the nodes.
     * @throws Exception
     */
    public JSONObject GetCookbooks() throws Exception {
        String Path = this.PathSuffix + "/cookbooks";
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    /**
     * Gets a list of all Nodes in the system along with the URI's to get additional details
     * @return - JSONObject - Returns a hash of uri's for the nodes.
     * @throws Exception
     */
    public JSONObject GetCookbook(String CookbookURI) throws Exception {
        String Path = this.PathSuffix + "/cookbooks/" + CookbookURI + "/_latest";
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    /**
     * Gets a list of all Nodes in the system along with the URI's to get additional details
     * @return - JSONObject - Returns a hash of uri's for the nodes.
     * @throws Exception
     */
    public JSONObject GetNodes() throws Exception {
        String Path = this.PathSuffix + "/nodes";
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    /**
     * Gets a list of all Roles in the system along with the URI's to get additional details
     * @return - JSONObject - Returns a hash of uri's for the roles.
     * @throws Exception
     */
    public JSONObject GetRoles() throws Exception {
        String Path = this.PathSuffix + "/roles";
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    /**
     * Gets a specific role and it details
     * @return - JSONObject - Returns details of a role
     * @throws Exception
     */
    public JSONObject GetRole(String URI) throws Exception {
        String Path = this.PathSuffix + "/roles/" + URI;
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    public Boolean UpdateRole(JSONObject JSON) throws Exception {
        String Path = this.PathSuffix + "/roles/" + JSON.getString("name");
        this.httpput = new HttpPut(this.ChefURL + Path);
        Log.i("UpdateNodewithRawJSON", Path);
        Log.i("UpdateNodewithRawJSON", JSON.toString(3));
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, JSON.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(JSON.toString()));

        httpClient.execute(this.httpput, responseHandler);

        return true;
    }

    public Boolean UpdateRolewithRawJSON(String RoleURI, JSONObject JSON) throws Exception {
        String Path = this.PathSuffix + "/roles/" + RoleURI;
        this.httpput = new HttpPut(this.ChefURL + Path);
        Log.i("UpdateNodewithRawJSON", Path);
        Log.i("UpdateNodewithRawJSON", JSON.toString(3));
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, JSON.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(JSON.toString()));

        httpClient.execute(this.httpput, responseHandler);

        return true;
    }

    /**
     * Gets a list of all environments in the system along with the URI's to get additional details
     * @return - JSONObject - Returns a hash of uri's for the environments.
     * @throws Exception
     */
    public JSONObject GetEnvironments() throws Exception {
        String Path = this.PathSuffix + "/environments";
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    /**
     * Gets a specific environemnt and its details
     * @return - JSONObject - Returns details of a role
     * @throws Exception
     */
    public JSONObject GetEnvironment(String URI) throws Exception {
        String Path = this.PathSuffix + "/environments/" + URI;
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    public Boolean UpdateEnvironment(JSONObject JSON) throws Exception {
        String Path = this.PathSuffix + "/environments/" + JSON.getString("name");
        this.httpput = new HttpPut(this.ChefURL + Path);
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, JSON.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(JSON.toString()));

        httpClient.execute(this.httpput, responseHandler);

        return true;
    }

    public Boolean DeleteEnvironment(JSONObject JSON) throws Exception {
        String Path = this.PathSuffix + "/environments/" + JSON.getString("name");
        this.httpdelete = new HttpDelete(this.ChefURL + Path);
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "DELETE");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        httpClient.execute(this.httpdelete, responseHandler);

        return true;
    }

    public Boolean SetEnvironment(String NodeURI, String Environment) throws Exception {
        JSONObject NodeDetails = this.GetNode(NodeURI);
        NodeDetails.put("chef_environment", Environment);

        String Path = this.PathSuffix + "/nodes/" + NodeURI;
        this.httpput = new HttpPut(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, NodeDetails.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(NodeDetails.toString()));

        String jsonTempString = httpClient.execute(this.httpput, responseHandler);
        Log.i("JSONString:", jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);

        if (json.get("chef_environment").equals(Environment)) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean AddRunList(String NodeURI, String Role) throws Exception {
        JSONObject NodeDetails = this.GetNode(NodeURI);
        Log.i("NodeDetails", NodeDetails.toString(3));

        //TODO Replace with JSONObject.accumulate() at some point
        JSONArray RunList = NodeDetails.getJSONArray("run_list");
        RunList.put("role[" + Role + "]");
        NodeDetails.put("run_list", RunList);

        Log.i("NodeDetails2", NodeDetails.toString(3));

        String Path = this.PathSuffix + "/nodes/" + NodeURI;
        this.httpput = new HttpPut(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, NodeDetails.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(NodeDetails.toString()));
        httpClient.execute(this.httpput, responseHandler);
        //String jsonTempString = httpClient.execute(this.httpput, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        //JSONObject json = new JSONObject(jsonTempString);

        return true;
    }

    public Boolean UpdateNodewithRawJSON(String NodeURI, JSONObject JSON) throws Exception {
        String Path = this.PathSuffix + "/nodes/" + NodeURI;
        this.httpput = new HttpPut(this.ChefURL + Path);
        Log.i("UpdateNodewithRawJSON", Path);
        Log.i("UpdateNodewithRawJSON", JSON.toString(3));
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, JSON.toString(), "PUT");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpput.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        this.httpput.setEntity(new StringEntity(JSON.toString()));

        httpClient.execute(this.httpput, responseHandler);

        return true;
    }

    /**
     * Try and perform a chef function - it'll either succeed or throw an exception / return false
     * @return - Boolean - whether we logged in or not
     * @throws Exception
     */
    public Boolean ConfirmLogin() throws Exception {
        String Path = this.PathSuffix + "/clients/" + settings.getString("ClientName", "--");
        this.httpget = new HttpGet(this.ChefURL + Path);
        Log.i("ConfirmLogin", Path);
        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            Log.i("Headers", Headers.get(i).getName() + ":" + Headers.get(i).getValue());
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }

        String jsonTempString = httpClient.execute(this.httpget, responseHandler);

        JSONObject json = new JSONObject(jsonTempString);

        if (settings.getBoolean("OpenSourceChef", true) == true) {
            if (json.getString("chef_type").equals("client")) {
                return true;
            } else {
                return false;
            }
        } else {
            if (json.getString("clientname").equals(settings.getString("ClientName", "--"))) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * Get all the details about a particular node
     * @param URI - The unique name of the node in question
     * @return - JSONObject - Complete list of cookbook attributes, definitions, libraries and recipes that are required for this node
     * @throws Exception
     */
    public JSONObject GetNode(String URI) throws Exception {
        String Path = this.PathSuffix + "/nodes/" + URI;
        this.httpget = new HttpGet(this.ChefURL + Path);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    public HashMap<String, String> CanonicalizeNode(JSONObject Node) {
        HashMap<String, String> CanonicalNode = new HashMap<String, String>();

        //TODO Make some form of awesome array to do this in a loop
        try {
            CanonicalNode.put("serial_number", Node.getJSONObject("automatic").getJSONObject("dmi")
                    .getJSONObject("system").getString("serial_number"));
        } catch (JSONException e) {
            CanonicalNode.put("serial_number", "Serial Number Not Found");
        }

        try {
            CanonicalNode.put("sku_number", Node.getJSONObject("automatic").getJSONObject("dmi")
                    .getJSONObject("system").getString("sku_number"));
        } catch (JSONException e) {
            CanonicalNode.put("sku_number", "SKU Not Found");
        }

        try {
            CanonicalNode.put("family", Node.getJSONObject("automatic").getJSONObject("dmi").getJSONObject("system")
                    .getString("family"));
        } catch (JSONException e) {
            CanonicalNode.put("family", "Unknown OS");
        }

        try {
            CanonicalNode.put("uptime", Node.getJSONObject("automatic").getString("uptime"));
            //Log.i("uptime",Node.getJSONObject("automatic").getString("uptime"));
        } catch (JSONException e) {
            CanonicalNode.put("uptime", "Uptime unknown");
        }

        try {
            CanonicalNode.put("chef_environment", "Environment: " + Node.getString("chef_environment"));
        } catch (JSONException e) {
            CanonicalNode.put("chef_environment", "Chef Environment Unknown");
        }

        try {
            CanonicalNode.put("cpuCountString",
                    Node.getJSONObject("automatic").getJSONObject("cpu").getString("real") + " / "
                            + Node.getJSONObject("automatic").getJSONObject("cpu").getString("total"));
        } catch (JSONException e) {
            CanonicalNode.put("cpuCountString", "0 / 0");
        }

        try {
            CanonicalNode.put("ramStatsString",
                    Node.getJSONObject("automatic").getJSONObject("memory").getString("total") + " / "
                            + Node.getJSONObject("automatic").getJSONObject("memory").getString("free"));
        } catch (JSONException e) {
            CanonicalNode.put("ramStatsString", "0kB Total / 0kB Free");
        }

        try {
            CanonicalNode.put("platform", Node.getJSONObject("automatic").getString("platform"));
        } catch (JSONException e) {
            CanonicalNode.put("platform", "");
        }

        try {
            JSONArray runListArray = Node.getJSONArray("run_list");
            String runList = "";
            for (int i = 0; i < runListArray.length(); i++) {
                runList += runListArray.getString(i);
                if (i != runListArray.length() - 1)
                    runList += ", ";
            }

            CanonicalNode.put("run_list", runList);
            //Log.i("CanonicalizeNode",runList);
        } catch (JSONException e) {
            CanonicalNode.put("run_list", "Unknown");
        }

        return CanonicalNode;
    }

    public JSONObject Search(String Query, String Index) throws Exception {
        String Path = this.PathSuffix + "/search/" + Index;

        Query = Query.replace(' ', '*');

        if (Index.equals("node")) {
            this.httpget = new HttpGet(this.ChefURL + Path + "?q=name:*" + Query + "*%20OR%20role:*" + Query + "*");
        } else {
            this.httpget = new HttpGet(this.ChefURL + Path + "?q=name:*" + Query + "*");
        }

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        //Log.i("JSONString:",jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }

    public JSONObject CraftedSearch(String Query, String Index) throws Exception {
        String Path = this.PathSuffix + "/search/" + Index.toLowerCase();

        Query = Query.replace(" ", "%20");

        this.httpget = new HttpGet(this.ChefURL + Path.toLowerCase() + "?q=" + Query);

        List<NameValuePair> Headers = ChefAuth.GetHeaders(Path, "", "GET");
        for (int i = 0; i < Headers.size(); i++) {
            this.httpget.setHeader(Headers.get(i).getName(), Headers.get(i).getValue());
        }
        String jsonTempString = httpClient.execute(this.httpget, responseHandler);
        Log.i("CraftedSearch JSONString:", jsonTempString);
        JSONObject json = new JSONObject(jsonTempString);
        return json;
    }
}