示例#1
0
        private int RunAutomation(GuidCollection bulletins)
        {
            Console.Write("\n\n");
            string now = DateTime.Now.ToString("yyyyMMddHHmmss");

            operation_log = "journal_" + now.ToString() + ".log";

            int i = 0;

            try {
                SecurityContextManager.SetContextData();
                PatchAPI wrap = new PatchAPI();

                string name = "";

                if (config.Dry_Run)
                {
                    Console.WriteLine("\n######## THIS IS A DRY RUN ########");
                }
                foreach (Guid bulletin in bulletins)
                {
                    name = Item.GetItem(bulletin).Name;
                    Console.WriteLine("");
                    Console.WriteLine("Processing bulletin {0} ({1}) now.", name, bulletin);

                    if (wrap.IsStaged(bulletin.ToString()))
                    {
                        Console.WriteLine("\tThis bulletin is already staged.");
                    }
                    else
                    {
                        if (config.RecreateMissingPolicies || config.Retarget)
                        {
                            // Skip this bulletin as it is not yet downloaded
                            continue;
                        }
                        Console.WriteLine("\t... bulletin will be staged now.");
                        if (!config.Dry_Run)
                        {
                            try {
                                wrap.EnsureStaged(bulletin.ToString(), true);
                                LogOp(String.Format("{0}: Staged bulletin {1} (guid={2}).", DateTime.Now.ToString(), name, bulletin.ToString()));
                            } catch {
                                // Do not retry staging error. Any download error is retried at the task level. Other errors won't be solved by retry...
                                if (config.ExcludeOnFail)
                                {
                                    DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + name + "')");
                                    Console.WriteLine("Failed to stage bulletin {0} - the bulletin is now excluded.", name);
                                }
                                else
                                {
                                    Console.WriteLine("Failed to stage bulletin {0} - skipping the bulletin now.", name);
                                }
                                continue; // Go to the next bulletin
                            }
                        }
                        Console.WriteLine("\tBulletin is now staged.");
                    }
                    Console.WriteLine("\tChecking if we need to create a new policy now.");

                    string   policies_str = wrap.ResolveToPolicies(bulletin.ToString());
                    string[] policies_arr = policies_str.Split(',');

                    if (!config.Retarget && (policies_str == "" || policies_str.Length == 0 || config.Create_Duplicates))
                    {
                        Console.WriteLine("\t... create a policy for the bulletin now.");
                        if (!config.Dry_Run)
                        {
                            int j = 0; // Used for retry count
retry_create_policy:
                            try {
                                if (config.Target_Guids.Count == 0)
                                {
                                    wrap.CreateUpdatePolicy(name, bulletin.ToString(), true);
                                    LogOp(String.Format("{0}: Created policy for bulletin {1} (guid={2})", DateTime.Now.ToString(), name, bulletin.ToString()));
                                }
                                else
                                {
                                    wrap.CreateUpdatePolicy(name, bulletin.ToString(), config.Target_Guids, true);
                                    LogOp(String.Format("{0}: Created policy for bulletin {1} (guid={2}, target={3})", DateTime.Now.ToString(), name, bulletin.ToString(), config.Get_TargetGuids()));
                                }
                                // Added the bulletin to the exclusion list here
                                if (config.Create_Duplicates)
                                {
                                    DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + name + "')");
                                }
                                i++;
                            } catch (Exception e) {
                                if (j++ < 3)
                                {
                                    Console.WriteLine(e.Message);
                                    Console.WriteLine(e.StackTrace);
                                    Console.WriteLine("\tFailed to create policy for bulletin {0} {1} time(s)...", name, j.ToString());
                                    goto retry_create_policy; // Retry ceiling not reach - let's do it again.
                                }
                                else                          // Retried 3 times - we quit and document the problem
                                {
                                    if (config.ExcludeOnFail)
                                    {
                                        DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + name + "')");
                                        Console.WriteLine("\tFailed to create policy for bulletin {0} 3 times - the bulletin is now excluded.", name);
                                    }
                                    else
                                    {
                                        Console.WriteLine("\tFailed to create policy for bulletin {0} 3 times - skipping the bulletin now.", name);
                                    }
                                    continue; // Go to the next bulletin
                                }
                            }
                        }
                        Console.WriteLine("\tSoftware update policy created!");
                    }
                    else if (config.Retarget)
                    {
                        if (policies_arr.Length > 0)
                        {
                            /* ENHANCEMENT: 2018-01-24; There is no need to update each policy - one of them will update the "parent" policy which is enough :D.
                             *                          This avoid doing the same task 153 times when an Office policy as 153 updates!
                             *
                             * */
                            //                            foreach (string p in policies_arr) {
                            string p = policies_arr[0];
                            if (p.Length != 36)
                            {
                                continue;
                            }

                            Console.WriteLine("\tA policy already exists for this bulletin...");

                            Guid policyGuid = new Guid(p);
                            SoftwareUpdateAdvertismentSetPolicy policyItem = Item.GetItem <SoftwareUpdateAdvertismentSetPolicy>(policyGuid, ItemLoadFlags.Writeable);

                            Console.WriteLine("\tPolicy {0} will be retargetted now.", policyItem.Name);

                            policyItem.ResourceTargets.Clear();
                            foreach (string target in config.Target_Guids)
                            {
                                policyItem.ResourceTargets.Add(new Guid(target));
                            }
                            if (!config.Dry_Run)
                            {
                                int retry = 0;
save_item:
                                try {
                                    policyItem.Save();
                                    LogOp(String.Format("{0}: Retargetted policy for bulletin {1} (guid={2}, new target={3})", DateTime.Now.ToString(), name, bulletin.ToString(), config.Get_TargetGuids()));
                                    i++;
                                } catch {
                                    Console.WriteLine("\tCaught an exception. Retry " + retry.ToString() + "will start now.");
                                    if (retry < 10)
                                    {
                                        goto save_item;
                                    }
                                    Console.WriteLine("\tSaving the policy failed 10 times. Moving on to the next item.");
                                }
                            }
//                            } // Commented out for each node removed to fix
                        }
                    }
                    else
                    {
                        Console.WriteLine("\tA policy already exists for this bulletin.");
                    }
                    if (i > 9 && config.Test_Run)
                    {
                        break;
                    }
                }
            } catch (Exception e) {
                Console.WriteLine("Error message={0}\nInner Exception={1}\nStacktrace={2}", e.Message, e.InnerException, e.StackTrace);
                return(-1);
            }
            return(i);
        }
        private int RunAutomation()
        {
            int i  = 0;
            int rc = 0;

            try {
                GuidCollection bulletins = new GuidCollection();
                bulletins = GetSoftwareBulletins();

                SecurityContextManager.SetContextData();
                PatchAPI wrap = new PatchAPI();

                if (config.Dry_Run)
                {
                    Console.WriteLine("\n######## THIS IS A DRY RUN ########");
                }

                foreach (Guid bulletin in bulletins)
                {
                    string bulletin_name = Item.GetItem(bulletin).Name;
                    Console.WriteLine("\n### BEGIN {0}, {1}", bulletin_name, bulletin);
                    if (wrap.IsStaged(bulletin.ToString()))
                    {
                        Console.WriteLine("PHASE 1: This bulletin is already staged.");
                    }
                    else
                    {
                        Console.WriteLine("PHASE 1: This bulletin will be staged now.");
                        if (!config.Dry_Run)
                        {
                            try {
                                EventLog.ReportInfo(String.Format("Bulletin {0} will be staged now.", bulletin_name));
                                wrap.EnsureStaged(bulletin.ToString(), true);
                            } catch {
                                // Do not retry staging error. Any download error is retried at the task level. Other errors won't be solved by retry...
                                if (config.ExcludeOnFail)
                                {
                                    DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + bulletin_name + "')");
                                    EventLog.ReportError(String.Format("Failed to stage bulletin {0} 3 times - the bulletin is now excluded.", bulletin_name));
                                }
                                else
                                {
                                    EventLog.ReportError(String.Format("Failed to stage bulletin {0} 3 times - skipping the bulletin now.", bulletin_name));
                                }
                                continue;
                            }
                        }
                    }

                    string policyGuids = "";
                    policyGuids = wrap.ResolveToPolicies(bulletin.ToString());

                    if (policyGuids == "" || policyGuids.Length == 0 || config.Create_Duplicates)
                    {
                        string date        = DateTime.Today.ToString("yyyy-MM-dd");
                        string policy_name = bulletin_name + ", " + config.POLICY_TEST + ", " + date;

                        Console.WriteLine("PHASE 2: Creating policy {0} now.", policy_name);
                        if (!config.Dry_Run)
                        {
                            int k = 0; //retry counter
retry_policy_creation:
                            try {
                                wrap.CreateUpdatePolicy(policy_name, bulletin.ToString(), config.Target_Guid_Test, true);
                                EventLog.ReportInfo(String.Format("SoftwareUpdateAdvertisement policy {0} (targetguid={1}) was created.", policy_name, config.Target_Guid_Test));
                            } catch {
                                if (k++ < 3)   // Policy creation  is retried 3 times - as the most likely fail case i deadlock.
                                {
                                    EventLog.ReportWarning(String.Format("Failed to create policy for bulletin {0} {1} times...", bulletin_name, k.ToString()));
                                    goto retry_policy_creation;
                                }
                                else     // Failed three times - skip or exclude based on CLI config
                                {
                                    if (config.ExcludeOnFail)
                                    {
                                        DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + bulletin_name + "')");
                                        EventLog.ReportError(String.Format("Failed to create policy for bulletin {0} 3 times - the bulletin is now excluded.", bulletin_name));
                                    }
                                    else
                                    {
                                        EventLog.ReportError(String.Format("Failed to create policy for bulletin {0} 3 times - skipping the bulletin now.", bulletin_name));
                                    }
                                    continue;
                                }
                            }
                            if (config.Create_Duplicates)
                            {
                                DatabaseAPI.ExecuteNonQuery("insert patchautomation_excluded (bulletin) values ('" + bulletin_name + "')");
                            }
                            i++;
                        }
                        Console.WriteLine("\tSoftware update policy created!");
                    }
                    else
                    {
                        Console.WriteLine("PHASE 2: Policy already exists.");
                        string[] _policyGuids = policyGuids.Split(',');
                        foreach (string policy in _policyGuids)
                        {
                            Guid   policyGuid = new Guid(policy);
                            string policyName = Item.GetItem(policyGuid).Name;

                            if (policyName.Contains(config.POLICY_TEST))
                            {
                                string timestamp = policyName.Substring(policyName.Length - 10);

                                DateTime policyDate = DateTime.Parse(timestamp);
                                TimeSpan ts         = DateTime.Today - policyDate;
                                if (ts.Days >= config.Span_Test_To_Validation)
                                {
                                    Console.WriteLine("PHASE 3: Policy needs retargetting (test -> validation)");
                                    this.UpdatePolicy("TEST_TO_VALIDATION", policyGuid, timestamp);
                                }
                                else
                                {
                                    Console.WriteLine("PHASE 3: Policy '{0}' doesn't need re-targetting.", policyName);
                                }
                            }
                            else if (policyName.Contains(config.POLICY_VALIDATED))
                            {
                                string timestamp = policyName.Substring(policyName.Length - 10);

                                DateTime policyDate = DateTime.Parse(timestamp);
                                TimeSpan ts         = DateTime.Today - policyDate;
                                if (ts.Days >= config.Span_Validation_To_Production)
                                {
                                    Console.WriteLine("PHASE 4: Policy needs retargetting (validation -> production)");
                                    this.UpdatePolicy("VALIDATION_TO_PRODUCTION", policyGuid, timestamp);
                                }
                                else
                                {
                                    Console.WriteLine("PHASE 4: Policy '{0}' doesn't need re-targetting.", policyName);
                                }
                            }
                        }
                    }
                    if (i == 10 && config.Test_Run)
                    {
                        break; // Limit the staging to 10 bulletin whilst testing
                    }
                    Console.WriteLine("### END");
                    rc = 0;
                }
            } catch (Exception e) {
                LoggingAPI.ReportException(e);
                rc = -2;
            }

            Console.WriteLine("\n{0} software update policy creation tasks were started.", i.ToString());
            return(rc);
        }