Esempio n. 1
0
        public Function BuildRunList()
        {
            ReturnType rt = new ReturnType();

            Logger.log("info", "Building run list...");
            RegistryHelper rh = new RegistryHelper {
                SubKey = "SOFTWARE\\Blu\\Runtime\\RunList\\"
            };

            rh.DeleteSubKeyTree();

            List <object> draftRunlist = (List <object>)ChefEndpoint.Get("nodes/" + ChefConfig.NodeName, "run_list").Object;

            // TODO: handle roles in the runlist
            // Only extract recipe[] runlist for now, role[] is not handled yet
            foreach (string item in draftRunlist)
            {
                Cookbook cookbook     = new Cookbook();
                string   recipe       = item.StringBetween("recipe[", "]");
                string[] runlistItem  = Regex.Split(recipe, @"::");
                string   cookbookName = runlistItem[0];

                // Add runlist item to sprint runlist
                string recipeName        = runlistItem.Count() < 2 ? "default" : runlistItem[1];
                string sprintRunListItem = SprintData.RunlistPath + "\\" + cookbookName + "\\recipes\\" + recipeName + ".rb";
                SprintData.SprintRunList.Add(sprintRunListItem);

                // Download cookbooks and extract resource/attribute list
                rt = cookbook.Download(cookbookName, String.Empty, String.Empty, String.Empty, true, true, true);
                SprintData.ResourceFileList.AddRange(cookbook.ResourceList);
                SprintData.AttributeFileList.AddRange(cookbook.AttributeList);
            }
            return(rt);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks if a cookbook supports blu. in metadata: supports 'blu'
        /// </summary>
        /// <param name="cookbookName">The name of the cookbook</param>
        /// <returns>Returns true if cookbook supports blu</returns>
        private static bool SupportsBlu(string cookbookName)
        {
            Dictionary <string, dynamic> platforms =
                (Dictionary <string, dynamic>)ChefEndpoint.Get("cookbooks/" + cookbookName + "/_latest", "metadata/platforms").Object;

            return(platforms.ContainsKey("blu"));
        }
Esempio n. 3
0
        private void btnGet_Click(object sender, EventArgs e)
        {
            txtError.Text = String.Empty;
            try
            {
                string path = "/";
                if (txtSelect.Text != "")
                {
                    path = txtPath.Text;
                }

                ReturnType rt = ChefEndpoint.Get(txtSelect.Text, path);
                if (rt.Result == 0)
                {
                    jvResponse.Json = rt.Data;
                }
                else
                {
                    txtError.Text = rt.Message;
                }
            }
            catch (Exception ex)
            {
                txtError.Text = "Unable to GET data: \r\n" + ex.Message +
                                "\r\nCan not find the requested endpoint on the Chef server.";
            }
        }
Esempio n. 4
0
        private void ExportSingleNodeRepository(string node, string folder)
        {
            ReturnType rt = new ReturnType();
            string     installedPackages = "";

            try
            {
                rt = ChefEndpoint.Get("nodes/" + node, "default/app_inventory/installed_packages");
                if (rt.Result == 0)
                {
                    installedPackages = rt.Data;
                }
            }
            catch (Exception ex)
            {
                txtError.Text = "Error getting Chef endpoint: " + ex.Message;
            }

            if (!string.IsNullOrEmpty(installedPackages))
            {
                try
                {
                    File.WriteAllText(folder + "\\" + node + ".json", installedPackages);
                }
                catch (Exception ex)
                {
                    txtError.Text = "Error exporting json: " + ex.Message;
                }
            }
        }
Esempio n. 5
0
        private void ExportSoftwareRepository()
        {
            string folder = String.Empty;
            Dictionary <string, dynamic> nodeList = new Dictionary <string, dynamic>();

            try
            {
                var          dialog = new System.Windows.Forms.FolderBrowserDialog();
                DialogResult result = dialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    folder   = dialog.SelectedPath;
                    nodeList = (Dictionary <string, dynamic>)ChefEndpoint.Get("nodes", "/").Object;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to Export data: \r\n" + ex.Message + "\r\nCan not find the requested endpoint on the Chef server.",
                                "Chef API Path Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            foreach (var node in nodeList)
            {
                ExportSingleNodeRepository(node.Key, folder);
            }
            MessageBox.Show("Chef endpoint is exported succcsfully.", "Export", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
Esempio n. 6
0
        /// <summary>
        /// Find version of the cookbook to download, based on the cookbook version operators, e.g. >=
        /// </summary>
        /// <param name="cookbookName">Cookbook name</param>
        /// <param name="version">Cookbook version</param>
        /// <param name="opr">Operator</param>
        /// <returns></returns>
        private static string FindVersion(string cookbookName, string version, string opr)
        {
            // If version is not specified, return "_latest" as version
            switch (version)
            {
            case "":
                return("_latest");

            case "latest":
                return("_latest");

            case "_latest":
                return(version);
            }

            // TODO: Make a better implementation of cookbook version requests
            string  foundVersion;
            Version latestVersion =
                new Version((String)ChefEndpoint.Get("cookbooks/" + cookbookName + "/_latest", "version").Object);
            Version requestedVersion = new Version(version);

            // TODO: fix this
            if (version == requestedVersion.ToString())
            {
                foundVersion = requestedVersion.ToString();
            }

            switch (opr)
            {
            case ">=":
                foundVersion = latestVersion >= requestedVersion?latestVersion.ToString() : String.Empty;

                break;

            case "~>":
                // returns String.Smily :)
                foundVersion = latestVersion >= requestedVersion?latestVersion.ToString() : String.Empty;

                break;

            // TODO: Cover other cookbook version comparison operators here
            default:
                foundVersion = String.Empty;
                break;
            }
            // Can not find a version of this cookbook
            if (foundVersion == String.Empty)
            {
                throw new InvalidOperationException("Can not find cookbook " + cookbookName + " " + opr + " " + version);
            }
            return(foundVersion);
        }
Esempio n. 7
0
        /// <summary>
        /// ChefApi GET method
        /// </summary>
        /// <param name="select">Select endpoint on Chef server</param>
        /// <param name="path">Search path</param>
        /// <returns>Chef server reply as dictionary, array or string</returns>
        public static object Get(string select, string path)
        {
            ReturnType rt = ChefEndpoint.Get(select, path);

            if (rt.Result == 0)
            {
                return(rt.Object);
            }
            else
            {
                throw new System.InvalidOperationException(rt.Message);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Convert cookbook json object to a dictionary of items
        /// </summary>
        /// <param name="cookbookName">Cookbook name</param>
        /// <param name="version">Cookbook version</param>
        /// <returns>Dictionary of cookbook items</returns>
        private static Dictionary <string, dynamic> CookbookToDictionary(string cookbookName, string version)
        {
            Dictionary <string, dynamic> cookbook;

            try
            {
                cookbook = (Dictionary <string, dynamic>)ChefEndpoint.Get("cookbooks/" + cookbookName + "/" + version, "/").Object;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Can not convert cookbook to a dictionary of items, Error : " + ex.Message);
            }
            return(cookbook);
        }
Esempio n. 9
0
        public void Connect()
        {
            // Check client connection
            Dictionary <string, dynamic> client = (Dictionary <string, dynamic>)ChefEndpoint.Get("clients/" + ChefConfig.ClientName, "/").Object;

            if (client.Count > 0)
            {
                // Show logo
                Host.UI.Write(ConsoleColor.DarkGray, Host.UI.RawUI.BackgroundColor, ChefConfig.BluLogo);
                Console.WriteLine();
                Logger.log("ok", "Connected!");
                Logger.log("info", "Client Name: " + ChefConfig.ClientName + " / Organization: " + ChefConfig.Organization);

                // Save Config
                ChefConfigurator chefConfigurator = new ChefConfigurator();
                chefConfigurator.SaveConfig();

                // Check if node exist
                Dictionary <string, dynamic> node = (Dictionary <string, dynamic>)ChefEndpoint.Get("nodes/" + ChefConfig.NodeName, "/").Object;
                if (node.Count > 0)
                {
                    Logger.log("ok", "Recieved Node json for: " + ChefConfig.NodeName);
                }
                else
                {
                    Console.WriteLine();
                    Logger.log("error", "Unable to retrieve Node data.");
                    Logger.log("info", "You are able to query Chef server by Use-ChefAPI CmdLet, but it seems the Chef node name you provided does not exist.");
                }
            }
            else
            {
                Console.WriteLine();
                string badNews = "Unable to connect as " + ChefConfig.ClientName + ".";
                Logger.log("error", badNews + " Please check if Chef client exists and the RSA key is valid.");
                Terminate(badNews);
            }
        }
Esempio n. 10
0
        public Object GetRunList()
        {
            Object runList = ChefEndpoint.Get("nodes/" + ChefConfig.NodeName, "run_list").Object;

            return(runList);
        }
Esempio n. 11
0
        /// <summary>
        /// Download a cookbook
        /// </summary>
        /// <param name="cookbookName">Cookbook name</param>
        /// <param name="version">Cookbook version</param>
        /// <param name="parent">For recursive adding all dependencies</param>
        /// <param name="opr">Operator e.g >= or ~></param>
        /// <param name="rewrite">Rewrite the cookbook folder</param>
        /// <param name="onlyBlu">Download only if it is a Blu cookbook: a cookbook which have [supports 'blu'] in metadata</param>
        /// <param name="addToRunlist">Add cookbook to the runlist registy key</param>
        /// <returns></returns>
        public Function Download(
            string cookbookName,
            string version,
            string parent,
            string opr,
            bool rewrite,
            bool onlyBlu,
            bool addToRunlist
            )
        {
            ReturnType rt           = new ReturnType();
            string     cookbookPath = CookbookRoot + "\\" + cookbookName;

            // Set response to OK now. It will be overridden if there is an error
            rt.Result  = 0;
            rt.Data    = String.Empty;
            rt.Object  = null;
            rt.Message = String.Empty;

            if (onlyBlu && !SupportsBlu(cookbookName))
            {
                throw new InvalidOperationException("Cookbook " + cookbookName + " does not suppport blu. Are you missing [supports 'blu'] directive in metadata?");
            }

            if (rewrite)
            {
                cookbookPath.EmptyFolder();
            }

            version = FindVersion(cookbookName, version, opr);
            Dictionary <string, dynamic> cookbook = CookbookToDictionary(cookbookName, version);

            // Loop through dictionary and find items
            foreach (KeyValuePair <string, dynamic> entry in cookbook)
            {
                // Check if item.key is found in cookbook structure (defined in ChefConfig.cookbookStructure)
                if (Array.IndexOf(ChefConfig.CookbookStructure, entry.Key) > -1)
                {
                    try
                    {
                        // Create a list of cookbook item which are valid to download
                        List <object> items = (List <object>)entry.Value;

                        // Put each List item into a dictionary
                        foreach (Dictionary <string, dynamic> item in items)
                        {
                            try
                            {
                                // Create each item path in filesystem
                                string itemPath = Path.GetDirectoryName(cookbookPath + "\\" + item["path"]);
                                if (itemPath != null && !Directory.Exists(itemPath))
                                {
                                    Directory.CreateDirectory(itemPath);
                                }
                                // Download item
                                using (var client = new WebClient())
                                {
                                    // Do not download BluStation.dll from blu_sprint cookbook
                                    // This file should already exist in the root, either by Bootstrap or Chef-Client run
                                    string itemFileName = Path.GetFileName(item["path"]);
                                    if (itemFileName != null && itemFileName.ToUpper() == "BLUSTATION.DLL")
                                    {
                                        continue;
                                    }

                                    // Download item
                                    client.DownloadFile(item["url"], cookbookPath + "\\" + item["path"]);
                                    string itemFolder            = Path.GetDirectoryName(item["path"]);
                                    string itemPathWindowsFormat = item["path"];
                                    itemPathWindowsFormat = cookbookPath + "\\" + itemPathWindowsFormat.Replace("/", "\\");

                                    // Add item to resource list
                                    if (itemFolder != null && itemFolder.ToUpper() == "RESOURCES")
                                    {
                                        ResourceList.Add(itemPathWindowsFormat);
                                    }

                                    // Add item to attribute list
                                    if (itemFolder != null && itemFolder.ToUpper() == "ATTRIBUTES")
                                    {
                                        AttributeList.Add(itemPathWindowsFormat);
                                    }

                                    Logger.log("ok", "Received: " + cookbookName + " -> " + item["path"]);
                                }
                            }
                            catch (Exception ex)
                            {
                                rt.Result  = 3;
                                rt.Data    = String.Empty;
                                rt.Object  = null;
                                rt.Message = "Unable to download: " + cookbookPath + "\\" + item["path"] + " Error: " + ex.Message;
                                return(rt);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        rt.Result  = 3;
                        rt.Data    = String.Empty;
                        rt.Object  = null;
                        rt.Message = "Unable to cast cookbook to a list of items, Error : " + ex.Message;
                        return(rt);
                    }
                }
            }

            // Add cookbook to runlist registry key
            if (addToRunlist)
            {
                AddToRunList(cookbookName, cookbookPath, version, parent);
            }

            // Recursively download dependencies
            Dictionary <string, dynamic> cookbookDeps = (Dictionary <string, dynamic>)ChefEndpoint.Get("cookbooks/" + cookbookName + "/" + version, "metadata/dependencies").Object;

            foreach (KeyValuePair <string, dynamic> dep in cookbookDeps)
            {
                string ver = new Regex("[^0-9 .]").Replace(dep.Value, "").Replace(" ", "");
                string op  = new Regex("[^=~>]").Replace(dep.Value, "").Replace(" ", "");
                Download(dep.Key, ver, parent + "\\" + cookbookName, op, rewrite, onlyBlu, addToRunlist);
            }

            // Finally
            return(rt);
        }
Esempio n. 12
0
        protected override void ProcessRecord()
        {
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => Assembly.Load(AssemblyResolver.ResolveAssembly(args));
            ChefConfigurator chefConfigurator = new ChefConfigurator();

            chefConfigurator.LoadConfig();

            // Disable API log to console
            // ChefConfig.apiLog = false;

            // Default values for Node, Path and Format parameters
            if (Select == null)
            {
                if (string.IsNullOrEmpty(ChefConfig.NodeName))
                {
                    Select = "nodes/" + ChefConfig.NodeName;
                }
                else
                {
                    Select = "nodes";
                }
            }
            else
            {
                // Trim the first / from -Endpoint
                Select = Select.TrimStart('/');
            }

            if (Format == null)
            {
                Format = "DICTIONARY";
            }
            if (Path == null)
            {
                Path = "/";
            }

            ReturnType rt = ChefEndpoint.Get(Select, Path);

            if (rt.Result == 0)
            {
                // Determine if data is encrypted
                string key = String.Empty;
                if (Secret != null)
                {
                    Format = "SECRET";
                    key    = Secret;
                }
                else if (SecretFile != null)
                {
                    Format = "SECRET";
                    key    = File.ReadAllText(ChefConfig.Root + "\\" + SecretFile);
                }

                switch (Format.ToUpper())
                {
                case "JSON":
                    WriteObject(rt.Data);
                    break;

                case "DICTIONARY":
                    WriteObject(rt.Object);
                    break;

                default:
                    Logger.log("error", "Output format is not recognized. Accepted values are 'Json', 'Dictionary'");
                    Terminate("Unrecognized Format");
                    break;
                }
            }
            else
            {
                Terminate(rt.Message);
            }
        }
Esempio n. 13
0
        public Function Build()
        {
            ReturnType rt;

            // Check Connection to Chef API
            Logger.log("info", "Connecting to Chef API...");
            rt = ChefEndpoint.Get("nodes/" + ChefConfig.NodeName, "/");
            if (rt.Result != 0)
            {
                return(rt);
            }
            Logger.log("ok", "Connected!");

            // Disable apilog after succesfull connection (to keep the log clean and readable)
            ChefConfig.ApiLog = false;

            // Clean up
            // TODO: Do some magic with MD5 instead of simply deleting the folder content
            Logger.log("info", "Preparing Runtime folder.");
            SprintData.RunlistPath.EmptyFolder();
            SprintData.SprintRunList.Clear();
            SprintData.ResourceFileList.Clear();
            SprintData.AttributeFileList.Clear();

            // Build Runlist (defined in Sprint.Runlist)
            BuildRunList();
            if (rt.Result != 0)
            {
                return(rt);
            }

            // Import Header (defined in Sprint.Header)
            ImportHeader();

            // Define sprint cookbook depnding of the Mode paramter
            rt = DefineSprintCookbook(Mode);
            if (rt.Result != 0)
            {
                return(rt);
            }
            SprintData.SprintPath = rt.Data;

            // Import constant variables (defined in Sprint.Constants)
            ImportConstants();

            // Import Attributes (defined in Sprint.Attributes)
            ImportAttributes();

            // Import instant unit tests
            Logger.log("info", "Reading Test script: blu_sprint::test.blu.rb");
            rt = ImportTest();
            if (rt.Result != 0)
            {
                return(rt);
            }

            // Collect Resource Files (defined in SprintData.ResourceFileList)
            rt = CollectResources();
            if (rt.Result != 0)
            {
                return(rt);
            }

            // Collect Attribute Files (defined in SprintData.AttributeFileList)
            rt = CollectAttributes();
            if (rt.Result != 0)
            {
                return(rt);
            }

            // Collect Recipes
            rt = CollectRecipes();
            if (rt.Result != 0)
            {
                return(rt);
            }

            // Build Ruby Stack
            RubyStack = AttributesStack + Environment.NewLine + RecipeStack;

            // Compile Sprint
            Compile();

            // Write Ruby stack to RubyStack.rb file
            System.IO.File.WriteAllText(SprintData.RubyStack, RubyStack);

            // Write transpiled Resources.psm1 to file
            System.IO.File.WriteAllText(SprintData.CompiledSprint, SprintPs1Content);

            // Write transpiled Sprint.ps1 to file
            System.IO.File.WriteAllText(SprintData.CompiledResources, ResourcesPs1Content);

            return(rt);
        }