-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for remote management, ephemeral and api url in Win…
…dows installer
- Loading branch information
Showing
9 changed files
with
1,190 additions
and
771 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,62 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace SumoLogic.wixext | ||
{ | ||
public class Config | ||
{ | ||
public string InstallationToken { get; set; } | ||
public Dictionary<string, string> CollectorFields { get; set; } | ||
|
||
public Config() { | ||
this.CollectorFields = new Dictionary<string, string>(); | ||
} | ||
|
||
public void SetCollectorFieldsFromTags(string tags) | ||
{ | ||
if (tags.Length == 0) { return; } | ||
|
||
var tagsRx = new Regex(@"([^=,]+)=([^\0]+?)(?=,[^,]+=|$)", RegexOptions.Compiled); | ||
var matches = tagsRx.Matches(tags); | ||
|
||
if (matches.Count == 0) | ||
{ | ||
throw new TagsSyntaxException("tags were provided with invalid syntax"); | ||
} | ||
if (matches.Count > 10) | ||
{ | ||
throw new TagsLimitExceededException("the limit of 10 tags was exceeded"); | ||
} | ||
|
||
foreach (Match match in matches) | ||
{ | ||
if (match.Groups.Count != 3) | ||
{ | ||
Console.WriteLine("Groups: {0}", match.Groups.Count); | ||
var msg = string.Format("invalid syntax for tag: {0}", match.Value); | ||
throw new TagSyntaxException(msg); | ||
} | ||
var key = match.Groups[1].Value.Trim(); | ||
var value = match.Groups[2].Value.Trim(); | ||
|
||
if (key.Length > 255) | ||
{ | ||
var msg = string.Format("tag key exceeds maximum length of 255: {0}", key); | ||
throw new TagKeyLengthExceededException(msg); | ||
} | ||
if (value.Length > 200) | ||
{ | ||
var msg = string.Format("tag value exceeds maximum length of 200: {0}", value); | ||
throw new TagValueLengthExceededException(msg); | ||
} | ||
|
||
this.CollectorFields.Add(key, value); | ||
} | ||
} | ||
} | ||
} | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace SumoLogic.wixext | ||
{ | ||
public class Config | ||
{ | ||
public string InstallationToken { get; set; } | ||
public Dictionary<string, string> CollectorFields { get; set; } | ||
public bool RemotelyManaged { get; set; } | ||
public bool Ephemeral { get; set; } | ||
public string OpAmpFolder { get; set; } | ||
public string Api { get; set; } | ||
|
||
public Config() { | ||
this.CollectorFields = new Dictionary<string, string>(); | ||
} | ||
|
||
public void SetCollectorFieldsFromTags(string tags) | ||
{ | ||
if (tags.Length == 0) { return; } | ||
|
||
var tagsRx = new Regex(@"([^=,]+)=([^\0]+?)(?=,[^,]+=|$)", RegexOptions.Compiled); | ||
var matches = tagsRx.Matches(tags); | ||
|
||
if (matches.Count == 0) | ||
{ | ||
throw new TagsSyntaxException("tags were provided with invalid syntax"); | ||
} | ||
if (matches.Count > 10) | ||
{ | ||
throw new TagsLimitExceededException("the limit of 10 tags was exceeded"); | ||
} | ||
|
||
foreach (Match match in matches) | ||
{ | ||
if (match.Groups.Count != 3) | ||
{ | ||
Console.WriteLine("Groups: {0}", match.Groups.Count); | ||
var msg = string.Format("invalid syntax for tag: {0}", match.Value); | ||
throw new TagSyntaxException(msg); | ||
} | ||
var key = match.Groups[1].Value.Trim(); | ||
var value = match.Groups[2].Value.Trim(); | ||
|
||
if (key.Length > 255) | ||
{ | ||
var msg = string.Format("tag key exceeds maximum length of 255: {0}", key); | ||
throw new TagKeyLengthExceededException(msg); | ||
} | ||
if (value.Length > 200) | ||
{ | ||
var msg = string.Format("tag value exceeds maximum length of 200: {0}", value); | ||
throw new TagValueLengthExceededException(msg); | ||
} | ||
|
||
this.CollectorFields.Add(key, value); | ||
} | ||
} | ||
} | ||
} |
272 changes: 168 additions & 104 deletions
272
msi/SumoLogic.wixext/SumoLogic.wixext/ConfigUpdater.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,104 +1,168 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using YamlDotNet.RepresentationModel; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace SumoLogic.wixext | ||
{ | ||
public class ConfigUpdater | ||
{ | ||
public YamlDocument Document { get; set; } | ||
|
||
public ConfigUpdater(StreamReader streamReader) { | ||
try | ||
{ | ||
var ys = new YamlStream(); | ||
ys.Load(streamReader); | ||
if (ys.Documents.Count == 0) | ||
{ | ||
throw new EmptyConfigException("config file is empty"); | ||
} | ||
this.Document = ys.Documents[0]; | ||
} | ||
finally | ||
{ | ||
streamReader.Dispose(); | ||
} | ||
} | ||
|
||
public void Update(Config config) | ||
{ | ||
YamlMappingNode root = (YamlMappingNode)this.Document.RootNode; | ||
|
||
EnsureMapKey(root, "extensions"); | ||
YamlMappingNode extensions = (YamlMappingNode)root.Children["extensions"]; | ||
|
||
EnsureMapKey(extensions, "sumologic"); | ||
YamlMappingNode sumologic = (YamlMappingNode)extensions.Children["sumologic"]; | ||
|
||
if (config.InstallationToken != "") | ||
{ | ||
EnsureScalarKey(sumologic, "installation_token"); | ||
sumologic.Children["installation_token"] = config.InstallationToken; | ||
} | ||
|
||
if (config.CollectorFields.Count > 0) | ||
{ | ||
EnsureMapKey(sumologic, "collector_fields"); | ||
YamlMappingNode collectorFields = (YamlMappingNode)sumologic.Children["collector_fields"]; | ||
|
||
foreach (KeyValuePair<string, string> field in config.CollectorFields) | ||
{ | ||
EnsureScalarKey(collectorFields, field.Key); | ||
collectorFields.Children[field.Key] = field.Value; | ||
} | ||
} | ||
} | ||
|
||
public void Save(StreamWriter streamWriter) | ||
{ | ||
try | ||
{ | ||
var serializer = new Serializer(); | ||
serializer.Serialize(streamWriter, this.Document.RootNode); | ||
} | ||
finally | ||
{ | ||
streamWriter.Flush(); | ||
} | ||
} | ||
|
||
private void EnsureMapKey(YamlMappingNode node, string key) | ||
{ | ||
if (node.Children.ContainsKey(key)) | ||
{ | ||
if (node.Children[key].NodeType == YamlNodeType.Mapping) { | ||
return; | ||
} | ||
|
||
// TODO: is this how we want to handle incorrect node types? | ||
// YamlNode is wrong type, remove it | ||
node.Children.Remove(key); | ||
} | ||
// Add empty YamlMappingNode to key | ||
node.Children.Add(key, new YamlMappingNode()); | ||
} | ||
|
||
private void EnsureScalarKey(YamlMappingNode node, string key) | ||
{ | ||
if (node.Children.ContainsKey(key)) | ||
{ | ||
if (node.Children[key].NodeType == YamlNodeType.Scalar) | ||
{ | ||
return; | ||
} | ||
|
||
// TODO: is this how we want to handle incorrect node types? | ||
// YamlNode is wrong type, remove it | ||
node.Children.Remove(key); | ||
} | ||
// Add empty YamlScalarNode to key | ||
node.Children.Add(key, new YamlScalarNode()); | ||
} | ||
} | ||
} | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using YamlDotNet.RepresentationModel; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace SumoLogic.wixext | ||
{ | ||
public class ConfigUpdater | ||
{ | ||
public YamlDocument Document { get; set; } | ||
|
||
public ConfigUpdater(StreamReader streamReader) { | ||
try | ||
{ | ||
var ys = new YamlStream(); | ||
ys.Load(streamReader); | ||
if (ys.Documents.Count == 0) | ||
{ | ||
throw new EmptyConfigException("config file is empty"); | ||
} | ||
this.Document = ys.Documents[0]; | ||
} | ||
finally | ||
{ | ||
streamReader.Dispose(); | ||
} | ||
} | ||
|
||
public void Update(Config config) | ||
{ | ||
if (config.RemotelyManaged && string.IsNullOrEmpty(config.OpAmpFolder)) | ||
{ | ||
throw new MissingConfigurationException("OpAmpFolder"); | ||
} | ||
|
||
YamlMappingNode root = (YamlMappingNode)this.Document.RootNode; | ||
|
||
EnsureMapKey(root, "extensions"); | ||
YamlMappingNode extensions = (YamlMappingNode)root.Children["extensions"]; | ||
|
||
EnsureMapKey(extensions, "sumologic"); | ||
YamlMappingNode sumologic = (YamlMappingNode)extensions.Children["sumologic"]; | ||
|
||
if (config.InstallationToken != "") | ||
{ | ||
EnsureScalarKey(sumologic, "installation_token"); | ||
sumologic.Children["installation_token"] = config.InstallationToken; | ||
} | ||
|
||
if (config.CollectorFields.Count > 0) | ||
{ | ||
EnsureMapKey(sumologic, "collector_fields"); | ||
YamlMappingNode collectorFields = (YamlMappingNode)sumologic.Children["collector_fields"]; | ||
|
||
foreach (KeyValuePair<string, string> field in config.CollectorFields) | ||
{ | ||
EnsureScalarKey(collectorFields, field.Key); | ||
collectorFields.Children[field.Key] = field.Value; | ||
} | ||
} | ||
|
||
if (config.RemotelyManaged) | ||
{ | ||
EnsureMapKey(extensions, "opamp"); | ||
YamlMappingNode opamp = (YamlMappingNode)extensions.Children["opamp"]; | ||
EnsureScalarKey(opamp, "remote_configuration_directory"); | ||
opamp.Children["remote_configuration_directory"] = config.OpAmpFolder; | ||
|
||
// Add OpAmp extension to service section | ||
EnsureMapKey(root, "service"); | ||
YamlMappingNode service = (YamlMappingNode)root.Children["service"]; | ||
EnsureSequenceKey(service, "extensions"); | ||
YamlSequenceNode serviceExtensions = (YamlSequenceNode)service.Children["extensions"]; | ||
if (!serviceExtensions.Children.Contains("opamp")) | ||
{ | ||
serviceExtensions.Children.Add("opamp"); | ||
} | ||
} | ||
|
||
if (config.Ephemeral) | ||
{ | ||
EnsureScalarKey(sumologic, "ephemeral"); | ||
sumologic.Children["ephemeral"] = "true"; | ||
} | ||
|
||
if (!string.IsNullOrEmpty(config.Api)) | ||
{ | ||
EnsureScalarKey(sumologic, "api_base_url"); | ||
sumologic.Children["api_base_url"] = config.Api; | ||
} | ||
|
||
// Make sure the sumologic processor node is a map node, otherwise an empty string | ||
// is generated as the value instead of an empty node. | ||
if (root.Children.ContainsKey("processors")) | ||
{ | ||
EnsureMapKey(root, "processors"); | ||
YamlMappingNode processors = (YamlMappingNode)root.Children["processors"]; | ||
if (processors.Children.ContainsKey("sumologic")) | ||
{ | ||
EnsureMapKey(processors, "sumologic"); | ||
} | ||
} | ||
} | ||
|
||
public void Save(StreamWriter streamWriter) | ||
{ | ||
try | ||
{ | ||
var serializer = new Serializer(); | ||
serializer.Serialize(streamWriter, this.Document.RootNode); | ||
} | ||
finally | ||
{ | ||
streamWriter.Flush(); | ||
} | ||
} | ||
|
||
private void EnsureMapKey(YamlMappingNode node, string key) | ||
{ | ||
if (node.Children.ContainsKey(key)) | ||
{ | ||
if (node.Children[key].NodeType == YamlNodeType.Mapping) { | ||
return; | ||
} | ||
|
||
// TODO: is this how we want to handle incorrect node types? | ||
// YamlNode is wrong type, remove it | ||
node.Children.Remove(key); | ||
} | ||
// Add empty YamlMappingNode to key | ||
node.Children.Add(key, new YamlMappingNode()); | ||
} | ||
|
||
private void EnsureScalarKey(YamlMappingNode node, string key) | ||
{ | ||
if (node.Children.ContainsKey(key)) | ||
{ | ||
if (node.Children[key].NodeType == YamlNodeType.Scalar) | ||
{ | ||
return; | ||
} | ||
|
||
// TODO: is this how we want to handle incorrect node types? | ||
// YamlNode is wrong type, remove it | ||
node.Children.Remove(key); | ||
} | ||
// Add empty YamlScalarNode to key | ||
node.Children.Add(key, new YamlScalarNode()); | ||
} | ||
|
||
private void EnsureSequenceKey(YamlMappingNode node, string key) | ||
{ | ||
if (node.Children.ContainsKey(key)) | ||
{ | ||
if (node.Children[key].NodeType == YamlNodeType.Sequence) | ||
{ | ||
return; | ||
} | ||
|
||
// TODO: is this how we want to handle incorrect node types? | ||
// YamlNode is wrong type, remove it | ||
node.Children.Remove(key); | ||
} | ||
// Add empty YamlScalarNode to key | ||
node.Children.Add(key, new YamlSequenceNode()); | ||
} | ||
} | ||
} |
Oops, something went wrong.