/// <summary> /// Fields are displayed as a table in the attachment block /// </summary> /// <param name="title">The title of the field</param> /// <param name="text">The text within the field</param> /// <param name="isShort">Does it take up 1 space or 2? If true, it will take up 1 space.</param> public SlackAttachment AddField(string title, string text, bool isShort = false) { SlackField field = new SlackField() { title = title, text = text, isShort = isShort }; fields.Add(field); return(this); }
/// <summary> /// Create a SlackField /// </summary> /// <param name="title">Title of Slack Field</param> /// <param name="value">Message in the Slack Field</param> /// <param name="isShort">Make the field the whole length of the field, or false for not the whole length</param> /// <returns>A completed SlackField</returns> public SlackField CreateSlackField(string title, string value, bool isShort) { SlackField slackField = new SlackField { Title = title, Value = value, Short = isShort }; return(slackField); }
private void btn_SlackFieldAdd_Click(object sender, EventArgs e) { SlackField field = new SlackField { }; //needed params string title = tbox_SlackFieldTitle.Text; string value = tbox_SlackFieldValue.Text; bool isShort = cbox_SlackFieldShort.Checked; field = client.CreateSlackField(title, value, isShort); slackFields.Add(field); }
private SlackAttachment CreateAtt(OrdbokArticle ordbokArticle) { var text = !ordbokArticle.Tydinger.Any() ? ordbokArticle.Forklaring : ""; var att = new SlackAttachment("", "") { Color = "#aa6a0a", Fallback = ordbokArticle.Oppslagsord + " :: " + ordbokArticle.Forklaring + ". " + string.Join(",", ordbokArticle.Tydinger.Select(d => d.ToString())), Text = text }; foreach (var tyding in ordbokArticle.Tydinger) { var sf = new SlackField($"{tyding.Nummer}. {tyding.Tekst}", string.Join(", ", tyding.Eksempler)); att.Fields.Add(sf); } return(att); }
public static void Run([TimerTrigger("0 0 15 * * *")] TimerInfo myTimer, TraceWriter log) // 10:00AM eastern { log.Info($"{DateTime.Now} : Function starting..."); int sqlOffenses = 0; string botToken = Environment.GetEnvironmentVariable("botToken"); string ruleChange = Environment.GetEnvironmentVariable("UpdateRules"); string whiteList = Environment.GetEnvironmentVariable("WhiteList"); if (string.IsNullOrEmpty(botToken)) { log.Error($"{DateTime.Now} : One or more of the required app settings is missing, check the Azure portal to verify all parameters."); return; } var slackClient = new SlackClient(new HttpClient(), botToken); var slackPost = new SlackPost { Channel = Environment.GetEnvironmentVariable("channel"), Text = "Azure SQL FW Auditor findings" }; if (!bool.TryParse(ruleChange, out bool updateFwSetting)) { updateFwSetting = false; log.Info($"{DateTime.Now} : Unable to parse 'UpdateRules' setting {ruleChange}. Defaulting to False"); } else { log.Info($"{DateTime.Now} : UpdateRules variable set to {updateFwSetting}"); } AzureCredentialsFactory credFactorty = new AzureCredentialsFactory(); var msi = new MSILoginInformation(MSIResourceType.AppService); var msiCred = credFactorty.FromMSI(msi, AzureEnvironment.AzureGlobalCloud); var azureAuth = Azure.Configure() .WithLogLevel(HttpLoggingDelegatingHandler.Level.BodyAndHeaders) .Authenticate(msiCred); var approvedRanges = string.IsNullOrEmpty(whiteList) ? ipRanges.ToList() : ipRanges.Union(whiteList.Split(',')).ToList(); log.Info($"{DateTime.Now} : Authenticated into tenant... Pulling subscriptions"); var fields = new List <SlackField>(); foreach (var sub in azureAuth.Subscriptions.List()) { log.Verbose($"{DateTime.Now} : Logging into subscription : {sub.SubscriptionId.ToString()}"); var azure = Azure.Configure() .WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic) .Authenticate(msiCred).WithSubscription(sub.SubscriptionId.ToString()); // loop through the sql servers in the subscription foreach (var server in azure.SqlServers.List()) { var outOfRangeRules = server.FirewallRules.List().Where(ruleDef => IsIpInRange(ruleDef.StartIPAddress, approvedRanges) == false || IsIpInRange(ruleDef.EndIPAddress, approvedRanges) == false); // process all the rules that are deemed bad foreach (var firewallRule in outOfRangeRules) { var field = new SlackField { Short = false, Title = " ", }; // The appsetting is set to true, so we try and delete the rule. if (updateFwSetting) { try { firewallRule.Delete(); field.Value = $"Server - {server.Name}, Firewall Rule(s) : \r\n>{firewallRule.Name} : {firewallRule.StartIPAddress} - {firewallRule.EndIPAddress} *Deleted : YES*"; } catch (Exception e) { field.Value = $"Server - {server.Name}, Firewall Rule(s) : \r\n>{firewallRule.Name} : {firewallRule.StartIPAddress} - {firewallRule.EndIPAddress} *Deleted : NO, encountered exception*"; log.Warning($"{DateTime.Now} : {e.Message}"); } } else { field.Value = $"{server.Name}, Firewall Rule(s) : \r\n>{firewallRule.Name} : {firewallRule.StartIPAddress} - {firewallRule.EndIPAddress} *Deleted : NO, deletion not enabled.*"; log.Info($"{DateTime.Now} : FW setting {updateFwSetting} firewall rule {firewallRule.Name} will be left to fester here"); } sqlOffenses++; } // Once its clean we add in missing ranges AddInMissingIpRanges(log, server); } } if (fields.Any()) { slackPost.Attachments = new List <SlackAttachment>() { new SlackAttachment { Fields = fields, Color = "ok", Title = " ", } }; _ = slackClient.PostToSlackAsync(slackPost); } }
/// <summary> /// DEFAULT GenerateSlackMessageAttachments function. /// </summary> /// <param name="logEvent">The log event.</param> /// <param name="formatProvider">A format provider</param> /// <param name="options">Sink Options as SlackSinkOptions.</param> /// <returns>The log message attachment list.</returns> public static List <SlackAttachment> GenerateSlackMessageAttachments(LogEvent logEvent, IFormatProvider formatProvider, object options) { // input check var slackSinkOptions = (SlackSinkOptions)options ?? throw new InvalidCastException(); var attachments = new List <SlackAttachment>(2); #region information attachment // Check if the short info attachment should be added if (slackSinkOptions.SlackAddShortInfoAttachment && !slackSinkOptions.SlackAddExtendedInfoAttachment) { // create the attachment var shotInfoAttach = new SlackAttachment { Actions = null, AuthorIcon = null, AuthorLink = null, AuthorName = null, CallbackId = null, Color = slackSinkOptions.SlackAttachmentColors[logEvent.Level], Fallback = $"{logEvent.Timestamp.ToString(formatProvider)} [{logEvent.Level}] - {logEvent.RenderMessage()}", Fields = new List <SlackField> { new SlackField { Short = slackSinkOptions.SlackDisplayShortInfoAttachmentShort, Title = "Level", Value = logEvent.Level.ToString() }, new SlackField { Short = slackSinkOptions.SlackDisplayShortInfoAttachmentShort, Title = "Timestamp", Value = logEvent.Timestamp.ToString(formatProvider) } }, Footer = null, FooterIcon = slackSinkOptions.SlackAttachmentFooterIcon[logEvent.Level], ImageUrl = null, MarkdownIn = null, Pretext = null, Text = null, ThumbUrl = null, Timestamp = 0, Title = "Details", TitleLink = null }; attachments.Add(shotInfoAttach); } // Check if the extended info attachment should be added else if (slackSinkOptions.SlackAddExtendedInfoAttachment) { var infoFields = new List <SlackField>(); var stringWriter = new StringWriter(); // collect all log event information foreach (var property in logEvent.Properties) { property.Value.Render(stringWriter, formatProvider: formatProvider); var field = new SlackField { Short = slackSinkOptions.SlackDisplayExtendedInfoAttachmentShort, Title = property.Key, Value = stringWriter.ToString() }; infoFields.Add(field); stringWriter.GetStringBuilder().Clear(); } // create the attachment var extInfoAttach = new SlackAttachment { Actions = null, AuthorIcon = null, AuthorLink = null, AuthorName = null, CallbackId = null, Color = slackSinkOptions.SlackAttachmentColors[logEvent.Level], Fallback = $"{logEvent.Timestamp.ToString(formatProvider)} [{logEvent.Level}] - {logEvent.RenderMessage()}", Fields = infoFields, Footer = null, FooterIcon = slackSinkOptions.SlackAttachmentFooterIcon[logEvent.Level], ImageUrl = null, MarkdownIn = null, Pretext = null, Text = null, ThumbUrl = null, Timestamp = 0, Title = "Details", TitleLink = null }; attachments.Add(extInfoAttach); } #endregion #region exception attachment // Check if the exception attachment should be added & if an exception is provided with to log event if (slackSinkOptions.SlackAddExceptionAttachment && logEvent.Exception != null) { // create the attachment var excAttach = new SlackAttachment { Actions = null, AuthorIcon = null, AuthorLink = null, AuthorName = null, CallbackId = null, Color = slackSinkOptions.SlackAttachmentColors[logEvent.Level], Fallback = $"{logEvent.Timestamp.ToString(formatProvider)} Exception: {logEvent.Exception.Message} \n {logEvent.Exception.StackTrace}", Fields = new List <SlackField> { new SlackField { Short = slackSinkOptions.SlackDisplayExceptionAttachmentShort, Title = "Message", Value = logEvent.Exception.Message }, new SlackField { Short = slackSinkOptions.SlackDisplayExceptionAttachmentShort, Title = "Type", Value = $"`{logEvent.Exception.GetType().Name}`" }, new SlackField { Short = false, Title = "Stack Trace", Value = $"```{logEvent.Exception.StackTrace}```" }, new SlackField { Short = false, Title = "Exception", Value = $"```{logEvent.Exception}```" } }, Footer = null, FooterIcon = slackSinkOptions.SlackAttachmentFooterIcon[logEvent.Level], ImageUrl = null, MarkdownIn = new List <string> { "fields" }, Pretext = null, Text = null, ThumbUrl = null, Timestamp = 0, Title = "Exception", TitleLink = null }; attachments.Add(excAttach); } #endregion return(attachments.Any() ? attachments : null); }