Example #1
0
 /// <summary>
 /// Runs a named Pyphon script that uses the DSL
 /// </summary>
 /// <param name="scriptname">The python script file</param>
 /// <param name="IAzureDevOpsProvider">The Azure DevOps provider</param>
 /// <param name="iEmailProvider">The email provider</param>
 /// <param name="iEventdataProvider">The raw data provider</param>
 public void RunScript(
     string scriptname,
     IAzureDevOpsProvider iAzureDevOpsProvider,
     IEmailProvider iEmailProvider,
     IEventDataProvider iEventdataProvider)
 {
     this.RunScript(
         FolderHelper.GetRootedPath(@"dsl"),
         FolderHelper.GetRootedPath("~/"),
         scriptname,
         null,
         iAzureDevOpsProvider,
         iEmailProvider,
         iEventdataProvider);
 }
Example #2
0
 /// <summary>
 /// Runs a named Pyphon script that uses the DSL
 /// </summary>
 /// <param name="scriptname">The python script file</param>
 /// <param name="args">The parameters to pass to the script</param>
 /// <param name="IAzureDevOpsProvider">The Azure DevOps provider</param>
 /// <param name="iEmailProvider">The email provider</param>
 /// <param name="iEventdataProvider">The raw data provider</param>
 public void RunScript(
     string scriptname,
     Dictionary <string, object> args,
     IAzureDevOpsProvider iAzureDevOpsProvider,
     IEmailProvider iEmailProvider,
     IEventDataProvider iEventdataProvider)
 {
     this.RunScript(
         FolderHelper.GetRootedPath(@"dsl"),
         FolderHelper.GetRootedPath("~/"),
         scriptname,
         args,
         iAzureDevOpsProvider,
         iEmailProvider,
         iEventdataProvider);
 }
Example #3
0
 /// <summary>
 /// Test constructor
 /// </summary>
 /// <param name="iEmailProvider">Email provider</param>
 /// <param name="iAzureDevOpsProvider">Smpt Provider</param>
 /// <param name="scriptFile">The script file to run</param>
 /// <param name="dslFolder">Folder to scan for DSL assemblies</param>
 public WebHookController(IEmailProvider iEmailProvider, IAzureDevOpsProvider iAzureDevOpsProvider, string scriptFile, string dslFolder)
 {
     this.iEmailProvider = iEmailProvider;
     this.scriptFile     = scriptFile;
     this.dslFolder      = dslFolder;
 }
Example #4
0
        [Authorize]                   // Require some form of authentication

        public HttpResponseMessage Post([FromBody] JObject jsondata)
        {
            try
            {
                if (ConfigHelper.ParseOrDefault(Microsoft.Azure.CloudConfigurationManager.GetSetting("LogEventsToFile")) == true)
                {
                    var logPath = ConfigHelper.GetLoggingPath();
                    logger.Info(string.Format("Post: Event being logged to [{0}]", logPath));
                    LoggingHelper.DumpEventToDisk(jsondata, logPath);
                }

                var dataProvider = new Providers.JsonDataProvider(jsondata);

                var uri         = dataProvider.GetServerUrl();
                var locationpat = ConfigHelper.GetPersonalAccessToken(uri);
                logger.Info($"Post: Using a {uri}");
                if (string.IsNullOrEmpty(locationpat.Item2) == false)
                {
                    logger.Info($"Post: Using a PAT token and obtained from {locationpat.Item1}");
                    this.iAzureDevOpsProvider = new Providers.AzureDevOpsProvider(uri, locationpat.Item2);
                }
                else
                {
                    logger.Info(string.Format("Post: Using default credentials and url {0}", uri));
                    this.iAzureDevOpsProvider = new Providers.AzureDevOpsProvider(uri);
                }

                // work out the event type
                var eventType = dataProvider.GetEventType();
                // work out the subscription ID
                var      subscriptionID = dataProvider.GetSubsriptionID();
                string[] argItems       = null;
                switch (eventType)
                {
                case "workitem.updated":
                case "workitem.created":
                case "workitem.deleted":
                case "workitem.restored":
                case "workitem.commented":
                    var workItemId = dataProvider.GetWorkItemDetails().Id;
                    if (workItemId > 0)
                    {
                        argItems = new[] { eventType, workItemId.ToString() };
                        logger.Info(
                            string.Format("Post: {1} Event being processed for WI:{0}", workItemId, eventType));
                    }
                    else
                    {
                        logger.Error(
                            string.Format("Post: {0} Event cannot find workitem ID", eventType));
                        return(new HttpResponseMessage(HttpStatusCode.BadRequest));
                    }
                    break;

                case "build.complete":
                    var buildDetails = dataProvider.GetBuildDetails();
                    argItems = new[] { eventType, buildDetails.Id.ToString() };
                    logger.Info(string.Format(
                                    "Post: Event being processed for Build:{0}",
                                    buildDetails.BuildUri));
                    break;

                case "ms.vss-release.deployment-approval-completed-event":
                case "ms.vss-release.deployment-approval-pending-event":
                case "ms.vss-release.deployment-completed-event":
                case "ms.vss-release.deployment-started-event":
                case "ms.vss-release.release-abandoned-event":
                case "ms.vss-release.release-created-event":
                    var releaseDetails = dataProvider.GetReleaseDetails();
                    argItems = new[] { eventType, releaseDetails.Id.ToString() };
                    logger.Info(string.Format(
                                    "Post: Event being processed for Release:{0}",
                                    releaseDetails.Id));
                    break;

                case "tfvc.checkin":
                    var checkInDetails = dataProvider.GetCheckInDetails();
                    argItems = new[] { eventType, checkInDetails.Changeset.ToString() };
                    logger.Info(
                        string.Format(
                            "Post: Event being processed for Checkin:{0}",
                            checkInDetails.Changeset));

                    break;

                case "message.posted":
                    var messagePostDetails = dataProvider.GetMessagePostDetails();
                    argItems = new[] { eventType, messagePostDetails.PostRoomId.ToString() };
                    logger.Info(
                        string.Format(
                            "Post: Event being processed for Meesage Post in Room:{0}",
                            messagePostDetails.PostRoomId));

                    break;

                case "git.push":
                    var pushDetails = dataProvider.GetPushDetails();
                    argItems = new[] { eventType, pushDetails.Repo, pushDetails.PushId.ToString() };
                    logger.Info(
                        string.Format(
                            "Post: Event being processed for Push:{0}",
                            pushDetails.PushId));

                    break;

                case "git.pullrequest.created":
                case "git.pullrequest.merged":
                case "git.pullrequest.updated":
                    var pullDetails = dataProvider.GetPullDetails();
                    argItems = new[] { eventType, pullDetails.Repo, pullDetails.PullId.ToString() };
                    logger.Info(
                        string.Format(
                            "Post: Event being processed for Pull:{0}",
                            pullDetails.PullId));

                    break;


                default:
                    logger.Info(string.Format("Post: Unhandled event cannot processed:{0}", eventType));
                    return(new HttpResponseMessage(HttpStatusCode.BadRequest));
                }

                var args = new Dictionary <string, object>
                {
                    { "Arguments", argItems },
                };

                var engine = new AzureDevOpsEventsProcessor.Dsl.DslProcessor(redirectScriptEngineOutputtoLogging);
                engine.RunScript(
                    this.dslFolder,
                    this.scriptFolder,
                    FolderHelper.GetScriptName(
                        eventType,
                        subscriptionID,
                        this.scriptFile,
                        this.useSubscriptionID),
                    args,
                    this.iAzureDevOpsProvider,
                    this.iEmailProvider,
                    dataProvider);


                return(new HttpResponseMessage(HttpStatusCode.OK));
            }
            catch (Exception ex)
            {
                // using a global exception catch to make sure we don't block any threads
                LoggingHelper.DumpException(logger, ex);

                return(new HttpResponseMessage(HttpStatusCode.BadRequest));
            }
        }
Example #5
0
 /// <summary>
 /// Constructor for DSL library
 /// </summary>
 /// <param name="IAzureDevOpsProvider">The Azure DevOps provider</param>
 /// <param name="iEmailProvider">The Email provider</param>
 public DslLibrary(IAzureDevOpsProvider iAzureDevOpsProvider, IEmailProvider iEmailProvider)
 {
     this.TfsProvider   = iAzureDevOpsProvider;
     this.EmailProvider = iEmailProvider;
 }
Example #6
0
        public void RunScript(
            string dslFolder,
            string scriptFolder,
            string scriptname,
            Dictionary <string, object> args,
            IAzureDevOpsProvider iAzureDevOpsProvider,
            IEmailProvider iEmailProvider,
            IEventDataProvider iEventData)
        {
            if (scriptname == null)
            {
                throw new ArgumentNullException("scriptname");
            }
            else
            {
                if (string.IsNullOrEmpty(scriptFolder))
                {
                    scriptFolder = FolderHelper.GetRootedPath("~/");
                }
                else
                {
                    scriptFolder = FolderHelper.GetRootedPath(scriptFolder);
                }

                if (File.Exists(scriptname) == false)
                {
                    // we have not been given a resolvable file name, so try appending the base path
                    scriptname = Path.Combine(scriptFolder, scriptname);
                    if (File.Exists(scriptname) == false)
                    {
                        this.logger.Error(string.Format("DslProcessor: DslProcessor cannot find script:{0}", scriptname));
                        return;
                    }
                }
            }

            if (iEventData == null)
            {
                throw new ArgumentNullException("iEventData");
            }

            if (iAzureDevOpsProvider == null)
            {
                throw new ArgumentNullException("iAzureDevOpsProvider");
            }

            if (iEmailProvider == null)
            {
                throw new ArgumentNullException("iEmailProvider");
            }

            if (string.IsNullOrEmpty(dslFolder))
            {
                dslFolder = FolderHelper.GetRootedPath("~/");
            }
            else
            {
                dslFolder = FolderHelper.GetRootedPath(dslFolder);
            }

            // load the DSL wrapper class via MEF
            //An aggregate catalog that combines multiple catalogs
            var catalog = new AggregateCatalog();

            //Adds all the parts found in the same assembly as the Program class
            if (Directory.Exists(dslFolder))
            {
                this.logger.Info(
                    string.Format("DslProcessor: DslProcessor loading DSL from {0}", Path.GetFullPath(dslFolder)));
                catalog.Catalogs.Add(new DirectoryCatalog(dslFolder));
            }
            else
            {
                this.logger.Error(
                    string.Format("DslProcessor: DslProcessor cannot find DSL folder {0}", Path.GetFullPath(dslFolder)));
                return;
            }

            try
            {
                //Create the CompositionContainer with the parts in the catalog
                var container = new CompositionContainer(catalog);

                container.ComposeParts(this);
            }
            catch (CompositionException compositionException)
            {
                this.logger.Error(string.Format("DsLProcessor: {0}", compositionException.Message));
                return;
            }
            catch (ReflectionTypeLoadException ex)
            {
                this.logger.Error(string.Format("DsLProcessor: {0}", ex.Message));
                StringBuilder sb = new StringBuilder();
                foreach (Exception exSub in ex.LoaderExceptions)
                {
                    sb.AppendLine(exSub.Message);
                    FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
                    if (exFileNotFound != null)
                    {
                        if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
                        {
                            sb.AppendLine("Fusion Log:");
                            sb.AppendLine(exFileNotFound.FusionLog);
                        }
                    }
                    sb.AppendLine();
                }
                this.logger.Error(string.Format("DslProcessor: {0}", sb.ToString()));
                return;
            }

            this.logger.Info(
                string.Format("DslProcessor: DslProcessor found  {0} DSL libraries", this.dslLibraries.Count()));

            if (this.dslLibraries.Any())
            {
                // create the engine
                var engine = IronPython.Hosting.Python.CreateEngine(args);
                var objOps = engine.Operations;
                var scope  = engine.CreateScope();

                // inject the providers
                foreach (var item in this.dslLibraries)
                {
                    item.EmailProvider = iEmailProvider;
                    item.TfsProvider   = iAzureDevOpsProvider;
                    item.EventData     = iEventData;
                    item.ScriptFolder  = scriptFolder;

                    // Read in the methods
                    foreach (string memberName in objOps.GetMemberNames(item))
                    {
                        scope.SetVariable(memberName, objOps.GetMember(item, memberName));
                    }
                }

                if (this.redirectScriptEngineOutputtoLogging == true)
                {
                    // redirect the console out opf the script to the nLog
                    engine.Runtime.IO.SetOutput(
                        new ConsoleRedirectStreamToNlog(LogLevel.Info, "PythonScriptConsole"),
                        System.Text.Encoding.ASCII);
                    engine.Runtime.IO.SetErrorOutput(
                        new ConsoleRedirectStreamToNlog(LogLevel.Error, "PythonScriptError"),
                        System.Text.Encoding.ASCII);
                }
                else
                {
                    // this is only used in tests where the console is visible or being cpatured in another manner
                    engine.Runtime.IO.RedirectToConsole();
                }

                // run the script
                this.logger.Info(string.Format(
                                     "DslProcessor: DslProcessor running script:{0}",
                                     scriptname));
                var script = engine.CreateScriptSourceFromFile(scriptname);
                script.Execute(scope);
            }
            else
            {
                this.logger.Error(
                    string.Format("DslProcessor: DslProcessor cannot find DSL libraries in folder {0}", Path.GetFullPath(dslFolder)));
                return;
            }
        }