From 7c11711ecb93aec14884bbc1cb2fad3f5e296f8f Mon Sep 17 00:00:00 2001 From: Larene Date: Tue, 23 Jun 2020 10:20:26 +1000 Subject: [PATCH 1/8] Bump version --- src/Seq.Api/Seq.Api.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Seq.Api/Seq.Api.csproj b/src/Seq.Api/Seq.Api.csproj index 0138235..65a1226 100644 --- a/src/Seq.Api/Seq.Api.csproj +++ b/src/Seq.Api/Seq.Api.csproj @@ -1,7 +1,7 @@ Client library for the Seq HTTP API. - 2020.1.0 + 2020.1.1 Datalust;Contributors netstandard2.0 true From b07c671e9f75d7db9072905cf6b017996b742627 Mon Sep 17 00:00:00 2001 From: larenelg Date: Mon, 31 Aug 2020 10:54:00 +1000 Subject: [PATCH 2/8] enable username password auth as admin / password --- example/SeqEnableAuth/Program.cs | 75 ++++++++++++++++++++++ example/SeqEnableAuth/SeqEnableAuth.csproj | 16 +++++ seq-api.sln | 7 ++ 3 files changed, 98 insertions(+) create mode 100644 example/SeqEnableAuth/Program.cs create mode 100644 example/SeqEnableAuth/SeqEnableAuth.csproj diff --git a/example/SeqEnableAuth/Program.cs b/example/SeqEnableAuth/Program.cs new file mode 100644 index 0000000..f92de48 --- /dev/null +++ b/example/SeqEnableAuth/Program.cs @@ -0,0 +1,75 @@ +using System; +using System.Threading.Tasks; +using DocoptNet; +using Seq.Api; +using Seq.Api.Model.Settings; + +namespace SeqEnableAuth +{ + class Program + { + const string Usage = @"seq-enable-auth: enable authentication on your Seq server. + +Usage: + seq-enable-auth.exe [--apikey=] + seq-enable-auth.exe (-h | --help) + +Options: + -h --help Show this screen. + --apikey= Seq API key. + + "; + static void Main(string[] args) + { + Task.Run(async () => + { + try + { + var arguments = new Docopt().Apply(Usage, args, version: "Seq Enable Auth 0.1", exit: true); + + var server = arguments[""].ToString(); + var apiKey = Normalize(arguments["--apikey"]); + + await Run(server, apiKey); + } + catch (Exception ex) + { + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Red; + Console.WriteLine("seq-enable-auth: {0}", ex); + Console.ResetColor(); + Environment.Exit(-1); + } + }).Wait(); + } + + static string Normalize(ValueObject v) + { + if (v == null) return null; + var s = v.ToString(); + return string.IsNullOrWhiteSpace(s) ? null : s; + } + + static async Task Run(string server, string apiKey) + { + var connection = new SeqConnection(server, apiKey); + + // check for valid license? + + var admin = await connection.Users.FindCurrentAsync(); + + admin.NewPassword = "password"; + + await connection.Users.UpdateAsync(admin); + + var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled); + iae.Value = true; + await connection.Settings.UpdateAsync(iae); + + await connection.Users.LoginAsync(admin.Username, "password"); + + var result = await connection.Users.FindAsync(admin.Id); + Console.WriteLine(result); + } + } +} diff --git a/example/SeqEnableAuth/SeqEnableAuth.csproj b/example/SeqEnableAuth/SeqEnableAuth.csproj new file mode 100644 index 0000000..9353a77 --- /dev/null +++ b/example/SeqEnableAuth/SeqEnableAuth.csproj @@ -0,0 +1,16 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + + + diff --git a/seq-api.sln b/seq-api.sln index 0c8feca..d55a021 100644 --- a/seq-api.sln +++ b/seq-api.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SeqTail", "example\SeqTail\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SignalCopy", "example\SignalCopy\SignalCopy.csproj", "{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeqEnableAuth", "example\SeqEnableAuth\SeqEnableAuth.csproj", "{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,6 +55,10 @@ Global {E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Debug|Any CPU.Build.0 = Debug|Any CPU {E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Release|Any CPU.ActiveCfg = Release|Any CPU {E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}.Release|Any CPU.Build.0 = Release|Any CPU + {035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -63,6 +69,7 @@ Global {34BBD428-8297-484E-B771-0B72C172C264} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487} {42CEBFBA-208F-40F1-AC95-13F05F6D5412} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487} {E8CDDE17-8E29-4EB4-A4BB-38BCE346A752} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487} + {035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55} = {1C66E116-DC21-4C8F-833E-A4C2DDF58487} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {20BAB483-FB94-4373-8E4C-0F846B6DBFFC} From 469b35e63695ae2e6a51478f1145c05c32c76c4e Mon Sep 17 00:00:00 2001 From: larenelg Date: Mon, 31 Aug 2020 14:51:55 +1000 Subject: [PATCH 3/8] add example for seq-enable-aad --- example/SeqEnableAAD/Program.cs | 88 +++++++++++++++++++ .../SeqEnableAAD.csproj} | 1 + example/SeqEnableAuth/Program.cs | 75 ---------------- seq-api.sln | 2 +- 4 files changed, 90 insertions(+), 76 deletions(-) create mode 100644 example/SeqEnableAAD/Program.cs rename example/{SeqEnableAuth/SeqEnableAuth.csproj => SeqEnableAAD/SeqEnableAAD.csproj} (88%) delete mode 100644 example/SeqEnableAuth/Program.cs diff --git a/example/SeqEnableAAD/Program.cs b/example/SeqEnableAAD/Program.cs new file mode 100644 index 0000000..a9a29fc --- /dev/null +++ b/example/SeqEnableAAD/Program.cs @@ -0,0 +1,88 @@ +using System; +using System.Threading.Tasks; +using DocoptNet; +using Seq.Api; +using Seq.Api.Model.Settings; + +namespace SeqEnableAAD +{ + class Program + { + const string Usage = @"seq-enable-aad: enable authentication on your Seq server (for initial setup of a new Seq server only). + +Usage: + seq-enable-aad.exe [--uname=] [--tenantid=] [--clientid=] [--clientkey=] (--authority=) + seq-enable-aad.exe (-h | --help) + +Options: + -h --help Show this screen. + --uname= Username. Azure Active Directory usernames must take the form of an email address. + --tenantid= Tenant ID. + --clientid= Client ID. + --clientkey= Client key. + --authority= Authority (optional, defaults to 'login.windows.net'). + "; + static void Main(string[] args) + { + Task.Run(async () => + { + try + { + var arguments = new Docopt().Apply(Usage, args, version: "Seq Enable AAD 0.1", exit: true); + + var server = arguments[""].ToString(); + var username = Normalize(arguments["--uname"]); + var tenantId = Normalize(arguments["--tenantid"]); + var clientId = Normalize(arguments["--clientid"]); + var clientKey = Normalize(arguments["--clientkey"]); + var authority = Normalize(arguments["--authority"]); + + await Run(server, username, tenantId, clientId, clientKey, authority); + } + catch (Exception ex) + { + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Red; + Console.WriteLine("seq-enable-auth: {0}", ex); + Console.ResetColor(); + Environment.Exit(-1); + } + }).Wait(); + } + + static string Normalize(ValueObject v) + { + if (v == null) return null; + var s = v.ToString(); + return string.IsNullOrWhiteSpace(s) ? null : s; + } + + static async Task Run(string server, string username, string tenantId, string clientId, string clientKey, string authority="login.windows.net") + { + var connection = new SeqConnection(server); + + var user = await connection.Users.FindCurrentAsync(); + var cid = await connection.Settings.FindNamedAsync(SettingName.AzureADClientId); + var ckey = await connection.Settings.FindNamedAsync(SettingName.AzureADClientKey); + var aut = await connection.Settings.FindNamedAsync(SettingName.AzureADAuthority); + var tid = await connection.Settings.FindNamedAsync(SettingName.AzureADTenantId); + + user.Username = username; + cid.Value = clientId; + ckey.Value = clientKey; + tid.Value = tenantId; + aut.Value = authority; + + await connection.Users.UpdateAsync(user); + await connection.Settings.UpdateAsync(cid); + await connection.Settings.UpdateAsync(ckey); + await connection.Settings.UpdateAsync(tid); + await connection.Settings.UpdateAsync(aut); + + + var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled); + iae.Value = true; + await connection.Settings.UpdateAsync(iae); // this update needs to happen last, as enabling auth will lock this connection out + } + } +} diff --git a/example/SeqEnableAuth/SeqEnableAuth.csproj b/example/SeqEnableAAD/SeqEnableAAD.csproj similarity index 88% rename from example/SeqEnableAuth/SeqEnableAuth.csproj rename to example/SeqEnableAAD/SeqEnableAAD.csproj index 9353a77..499ae03 100644 --- a/example/SeqEnableAuth/SeqEnableAuth.csproj +++ b/example/SeqEnableAAD/SeqEnableAAD.csproj @@ -3,6 +3,7 @@ Exe netcoreapp3.1 + SeqEnableAuth diff --git a/example/SeqEnableAuth/Program.cs b/example/SeqEnableAuth/Program.cs deleted file mode 100644 index f92de48..0000000 --- a/example/SeqEnableAuth/Program.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Threading.Tasks; -using DocoptNet; -using Seq.Api; -using Seq.Api.Model.Settings; - -namespace SeqEnableAuth -{ - class Program - { - const string Usage = @"seq-enable-auth: enable authentication on your Seq server. - -Usage: - seq-enable-auth.exe [--apikey=] - seq-enable-auth.exe (-h | --help) - -Options: - -h --help Show this screen. - --apikey= Seq API key. - - "; - static void Main(string[] args) - { - Task.Run(async () => - { - try - { - var arguments = new Docopt().Apply(Usage, args, version: "Seq Enable Auth 0.1", exit: true); - - var server = arguments[""].ToString(); - var apiKey = Normalize(arguments["--apikey"]); - - await Run(server, apiKey); - } - catch (Exception ex) - { - Console.ForegroundColor = ConsoleColor.White; - Console.BackgroundColor = ConsoleColor.Red; - Console.WriteLine("seq-enable-auth: {0}", ex); - Console.ResetColor(); - Environment.Exit(-1); - } - }).Wait(); - } - - static string Normalize(ValueObject v) - { - if (v == null) return null; - var s = v.ToString(); - return string.IsNullOrWhiteSpace(s) ? null : s; - } - - static async Task Run(string server, string apiKey) - { - var connection = new SeqConnection(server, apiKey); - - // check for valid license? - - var admin = await connection.Users.FindCurrentAsync(); - - admin.NewPassword = "password"; - - await connection.Users.UpdateAsync(admin); - - var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled); - iae.Value = true; - await connection.Settings.UpdateAsync(iae); - - await connection.Users.LoginAsync(admin.Username, "password"); - - var result = await connection.Users.FindAsync(admin.Id); - Console.WriteLine(result); - } - } -} diff --git a/seq-api.sln b/seq-api.sln index d55a021..8fda661 100644 --- a/seq-api.sln +++ b/seq-api.sln @@ -27,7 +27,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SeqTail", "example\SeqTail\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SignalCopy", "example\SignalCopy\SignalCopy.csproj", "{E8CDDE17-8E29-4EB4-A4BB-38BCE346A752}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeqEnableAuth", "example\SeqEnableAuth\SeqEnableAuth.csproj", "{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeqEnableAAD", "example\SeqEnableAAD\SeqEnableAAD.csproj", "{035B62FC-CAD7-4DF9-A2A3-FAAA64DF3B55}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From c036dbee4144bfd021692d6dc4ce269d77b8fd35 Mon Sep 17 00:00:00 2001 From: larenelg Date: Mon, 31 Aug 2020 15:12:24 +1000 Subject: [PATCH 4/8] fix missing provider update in add example, update how icon is included --- example/SeqEnableAAD/Program.cs | 5 ++++- src/Seq.Api/Seq.Api.csproj | 3 ++- src/Seq.Api/seq-api-icon.png | Bin 0 -> 6683 bytes 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 src/Seq.Api/seq-api-icon.png diff --git a/example/SeqEnableAAD/Program.cs b/example/SeqEnableAAD/Program.cs index a9a29fc..0935160 100644 --- a/example/SeqEnableAAD/Program.cs +++ b/example/SeqEnableAAD/Program.cs @@ -62,12 +62,14 @@ static async Task Run(string server, string username, string tenantId, string cl var connection = new SeqConnection(server); var user = await connection.Users.FindCurrentAsync(); + var provider = await connection.Settings.FindNamedAsync(SettingName.AuthenticationProvider); var cid = await connection.Settings.FindNamedAsync(SettingName.AzureADClientId); var ckey = await connection.Settings.FindNamedAsync(SettingName.AzureADClientKey); var aut = await connection.Settings.FindNamedAsync(SettingName.AzureADAuthority); var tid = await connection.Settings.FindNamedAsync(SettingName.AzureADTenantId); user.Username = username; + provider.Value = "Azure Active Directory"; cid.Value = clientId; ckey.Value = clientKey; tid.Value = tenantId; @@ -78,7 +80,8 @@ static async Task Run(string server, string username, string tenantId, string cl await connection.Settings.UpdateAsync(ckey); await connection.Settings.UpdateAsync(tid); await connection.Settings.UpdateAsync(aut); - + + await connection.Settings.UpdateAsync(provider); // needs to go before IsAuthenticationEnabled but after the other settings var iae = await connection.Settings.FindNamedAsync(SettingName.IsAuthenticationEnabled); iae.Value = true; diff --git a/src/Seq.Api/Seq.Api.csproj b/src/Seq.Api/Seq.Api.csproj index 65a1226..0de28ea 100644 --- a/src/Seq.Api/Seq.Api.csproj +++ b/src/Seq.Api/Seq.Api.csproj @@ -8,7 +8,7 @@ true seq Copyright © Datalust Pty Ltd and Contributors - https://datalust.co/images/seq-nuget.png + seq-api-icon.png https://github.com/datalust/seq-api Apache-2.0 8 @@ -16,5 +16,6 @@ + diff --git a/src/Seq.Api/seq-api-icon.png b/src/Seq.Api/seq-api-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ed37092a0647fa008fb640b51ac049a0e18f7472 GIT binary patch literal 6683 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

4EyzzsQ7ysoP= z8_lFxRNWc)AS9OH&X^m0ebJ-jIjIv-(g!M|WVeDVIG;XOwgfR?(Ggol@-mqZW+-8t zbiwj#G9bBFSDJ9Gb=_%XCWcj}VY%GEtchr5Ffk?9hiA0_)Ox{dMkh1?#z#r+W3DeIXKr#cs z__Zt^^bFHyLrqcBGdKf15UrF@!biY|uX{BHjYct_shB${-1fRBaN`e2QcF3@B+Q*~ zFz#m0q3%>ZE_>+j6G4T@YXHVW1FR8;hq>DRfc#}8%pK56bWfnb+1&zP7{UcI9KVAD?e*t6ti5;6#i zJCRQ22A#~OZvfLM07Bx%jh8N`jb3E@g_LMTlt?9Erg#N-D5AAGzn2m8=$M)(d(n_I z^lOw{kl)4o*05n8vI2HjQotW#cV^RiV#`P71G|d}CCuPdx78Z{wm?=vb-Rp_Z^e!f zTZ%D_5@07q9&J#DzgH3TyZ~>E-svwZ9i^@V~_JYx)z6$AD=kB0p=>EyA=59UT5>He4h ks__4Q0GT!4u_|%qCMi5^s9g^Hkb~%Go;_7`(k|?O0Xp`D!T Date: Mon, 31 Aug 2020 16:08:05 +1000 Subject: [PATCH 5/8] add extra info for AAD example --- example/SeqEnableAAD/Program.cs | 4 ++-- example/SeqEnableAAD/README.md | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 example/SeqEnableAAD/README.md diff --git a/example/SeqEnableAAD/Program.cs b/example/SeqEnableAAD/Program.cs index 0935160..259a6e1 100644 --- a/example/SeqEnableAAD/Program.cs +++ b/example/SeqEnableAAD/Program.cs @@ -11,7 +11,7 @@ class Program const string Usage = @"seq-enable-aad: enable authentication on your Seq server (for initial setup of a new Seq server only). Usage: - seq-enable-aad.exe [--uname=] [--tenantid=] [--clientid=] [--clientkey=] (--authority=) + seq-enable-aad.exe --uname= --tenantid= --clientid= --clientkey= [--authority=] seq-enable-aad.exe (-h | --help) Options: @@ -43,7 +43,7 @@ static void Main(string[] args) { Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.Red; - Console.WriteLine("seq-enable-auth: {0}", ex); + Console.WriteLine("seq-enable-aad: {0}", ex); Console.ResetColor(); Environment.Exit(-1); } diff --git a/example/SeqEnableAAD/README.md b/example/SeqEnableAAD/README.md new file mode 100644 index 0000000..14c67af --- /dev/null +++ b/example/SeqEnableAAD/README.md @@ -0,0 +1,34 @@ +# Seq Enable AAD (Azure Active Directory) + +Be sure to read the [Seq Azure Active Directory documentation](https://docs.datalust.co/docs/azure-active-directory) to find the manual AAD setup instructions. + +## Example usage: + +``` +seq-enable-aad.exe https://seq.example.com --uname=example@microsoft.com --clientid=xxxxxx --tenantid=xxxxxx --clientkey=xxxxxx --authority=login.windows.net +``` + +### **Important note:** + +#### Windows + +Don't forget to set the "canonical URI" which Seq uses as a reply address for AAD. + +``` +seq config -k api.canonicalUri -v https://seq.example.com +seq service restart +``` + +#### Linux / Docker + +Don't forget to include the BASE_URI which Seq uses as a reply address for AAD. + +``` +docker run -d \ + --restart unless-stopped \ + --name seq \ + -p 5341:80 \ + -e ACCEPT_EULA=Y \ + -e BASE_URI=https://seq.example.com \ + datalust/seq:latest +``` \ No newline at end of file From 11adc3e8da95d59d13b79284a116e97255a920c1 Mon Sep 17 00:00:00 2001 From: larenelg Date: Mon, 31 Aug 2020 20:44:14 +1000 Subject: [PATCH 6/8] rename master to release --- Build.ps1 | 2 +- README.md | 4 ++-- appveyor.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Build.ps1 b/Build.ps1 index ff877e2..41dbb82 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -14,7 +14,7 @@ if($LASTEXITCODE -ne 0) { exit 1 } $branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL]; $revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL]; -$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "master" -and $revision -ne "local"] +$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "release" -and $revision -ne "local"] echo "build: Version suffix is $suffix" diff --git a/README.md b/README.md index 71ee848..55a6974 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ var installedApps = await connection.Apps.ListAsync(); **To authenticate**, the `SeqConnection` constructor accepts an `apiKey` parameter (make sure the API key permits _user-level access_) or, if you want to log in with personal credentials you can `await connection.Users.LoginAsync(username, password)`. -For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/master/example/SeqTail/Program.cs). +For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/release/example/SeqTail/Program.cs). #### Creating entities @@ -43,7 +43,7 @@ signal.Title = "Signal 123"; await connection.Signals.AddAsync(signal); ``` -See the [signal-copy app](https://github.com/datalust/seq-api/blob/master/example/SignalCopy/Program.cs) for an example of this pattern in action. +See the [signal-copy app](https://github.com/datalust/seq-api/blob/release/example/SignalCopy/Program.cs) for an example of this pattern in action. ### Reading events diff --git a/appveyor.yml b/appveyor.yml index 4743d67..104b12e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,11 +12,11 @@ deploy: secure: sMicBLl7Z83H/mhX10DL7Yqwa80ZHUbb9fRHKmxd5m2MN2DWAE1kbYH/GPQPFajZ skip_symbols: true on: - branch: /^(master|dev)$/ + branch: /^(release|dev)$/ - provider: GitHub auth_token: secure: hX+cZmW+9BCXy7vyH8myWsYdtQHyzzil9K5yvjJv7dK9XmyrGYYDj/DPzMqsXSjo artifact: /Seq.Api.*\.nupkg/ tag: v$(appveyor_build_version) on: - branch: master + branch: release From e42b29b64f6a87c9e5e5892c30fbc3dbab74714d Mon Sep 17 00:00:00 2001 From: larenelg Date: Tue, 1 Sep 2020 10:29:48 +1000 Subject: [PATCH 7/8] use 'main' in our C# projects --- Build.ps1 | 2 +- README.md | 4 ++-- appveyor.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Build.ps1 b/Build.ps1 index 41dbb82..40b95c7 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -14,7 +14,7 @@ if($LASTEXITCODE -ne 0) { exit 1 } $branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL]; $revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL]; -$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "release" -and $revision -ne "local"] +$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"] echo "build: Version suffix is $suffix" diff --git a/README.md b/README.md index 55a6974..5ad2fc5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ var installedApps = await connection.Apps.ListAsync(); **To authenticate**, the `SeqConnection` constructor accepts an `apiKey` parameter (make sure the API key permits _user-level access_) or, if you want to log in with personal credentials you can `await connection.Users.LoginAsync(username, password)`. -For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/release/example/SeqTail/Program.cs). +For a more complete example, see the [seq-tail app included in the source](https://github.com/datalust/seq-api/blob/main/example/SeqTail/Program.cs). #### Creating entities @@ -43,7 +43,7 @@ signal.Title = "Signal 123"; await connection.Signals.AddAsync(signal); ``` -See the [signal-copy app](https://github.com/datalust/seq-api/blob/release/example/SignalCopy/Program.cs) for an example of this pattern in action. +See the [signal-copy app](https://github.com/datalust/seq-api/blob/main/example/SignalCopy/Program.cs) for an example of this pattern in action. ### Reading events diff --git a/appveyor.yml b/appveyor.yml index 104b12e..73bec11 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,11 +12,11 @@ deploy: secure: sMicBLl7Z83H/mhX10DL7Yqwa80ZHUbb9fRHKmxd5m2MN2DWAE1kbYH/GPQPFajZ skip_symbols: true on: - branch: /^(release|dev)$/ + branch: /^(main|dev)$/ - provider: GitHub auth_token: secure: hX+cZmW+9BCXy7vyH8myWsYdtQHyzzil9K5yvjJv7dK9XmyrGYYDj/DPzMqsXSjo artifact: /Seq.Api.*\.nupkg/ tag: v$(appveyor_build_version) on: - branch: release + branch: main From b2b3bb7d91d1d6c98062a0222ce38601ac77b402 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Thu, 12 Nov 2020 10:40:10 +1000 Subject: [PATCH 8/8] Updates for Seq 2020.4 --- .../Model/Diagnostics/ServerMetricsEntity.cs | 10 +++++ .../Storage/ColumnDescriptionPart.cs | 33 +++++++++++++++ .../Model/Diagnostics/Storage/ColumnType.cs | 19 +++++++++ .../Model/Diagnostics/Storage/RowsetPart.cs | 19 +++++++++ .../Storage/StorageConsumptionPart.cs | 41 +++++++++++++++++++ src/Seq.Api/Model/License/LicenseEntity.cs | 11 +++++ src/Seq.Api/Model/Shared/DateTimeRange.cs | 31 ++++++++++++++ .../DiagnosticsResourceGroup.cs | 33 ++++++++++++++- src/Seq.Api/Seq.Api.csproj | 4 +- 9 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 src/Seq.Api/Model/Diagnostics/Storage/ColumnDescriptionPart.cs create mode 100644 src/Seq.Api/Model/Diagnostics/Storage/ColumnType.cs create mode 100644 src/Seq.Api/Model/Diagnostics/Storage/RowsetPart.cs create mode 100644 src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs create mode 100644 src/Seq.Api/Model/Shared/DateTimeRange.cs diff --git a/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs b/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs index bca4e1c..6bb1079 100644 --- a/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs +++ b/src/Seq.Api/Model/Diagnostics/ServerMetricsEntity.cs @@ -28,6 +28,16 @@ public class ServerMetricsEntity : Entity public ServerMetricsEntity() { } + + ///

+ /// The start time in UTC of the events in the memory cache. + /// + public DateTime? EventStoreCacheStart { get; set; } + + /// + /// The end time in UTC of the events in the memory cache. + /// + public DateTime? EventStoreCacheEnd { get; set; } /// /// The number of days of events able to fit in the memory cache. diff --git a/src/Seq.Api/Model/Diagnostics/Storage/ColumnDescriptionPart.cs b/src/Seq.Api/Model/Diagnostics/Storage/ColumnDescriptionPart.cs new file mode 100644 index 0000000..9393642 --- /dev/null +++ b/src/Seq.Api/Model/Diagnostics/Storage/ColumnDescriptionPart.cs @@ -0,0 +1,33 @@ +using System; + +namespace Seq.Api.Model.Diagnostics.Storage +{ + /// + /// A description of a column in a rowset. + /// + public readonly struct ColumnDescriptionPart + { + /// + /// A label for the column. + /// + public string Label { get; } + + /// + /// Additional metadata describing the role of the column; this is separate from, + /// but related to, the runtime type of the column values. + /// + public ColumnType Type { get; } + + /// + /// Construct a . + /// + /// A label for the column. + /// Additional metadata describing the role of the column; this is separate from, + /// but related to, the runtime type of the column values. + public ColumnDescriptionPart(string label, ColumnType type) + { + Label = label ?? throw new ArgumentNullException(nameof(label)); + Type = type; + } + } +} \ No newline at end of file diff --git a/src/Seq.Api/Model/Diagnostics/Storage/ColumnType.cs b/src/Seq.Api/Model/Diagnostics/Storage/ColumnType.cs new file mode 100644 index 0000000..7de3e51 --- /dev/null +++ b/src/Seq.Api/Model/Diagnostics/Storage/ColumnType.cs @@ -0,0 +1,19 @@ +namespace Seq.Api.Model.Diagnostics.Storage +{ + /// + /// Additional metadata describing the role of a column; this is separate from, + /// but related to, the runtime type of the column values. + /// + public enum ColumnType + { + /// + /// The column contains general data. + /// + General, + + /// + /// The column contains timestamps that may be used to create a timeseries. + /// + Timestamp, + } +} \ No newline at end of file diff --git a/src/Seq.Api/Model/Diagnostics/Storage/RowsetPart.cs b/src/Seq.Api/Model/Diagnostics/Storage/RowsetPart.cs new file mode 100644 index 0000000..7632648 --- /dev/null +++ b/src/Seq.Api/Model/Diagnostics/Storage/RowsetPart.cs @@ -0,0 +1,19 @@ +namespace Seq.Api.Model.Diagnostics.Storage +{ + /// + /// Values in rows and columns. + /// + public class RowsetPart + { + /// + /// The columns of the rowset. + /// + public ColumnDescriptionPart[] Columns { get; set; } + + /// + /// An array of rows, where each row is an array of values + /// corresponding to the columns of the rowset. + /// + public object[][] Rows { get; set; } + } +} \ No newline at end of file diff --git a/src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs b/src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs new file mode 100644 index 0000000..4cbed6b --- /dev/null +++ b/src/Seq.Api/Model/Diagnostics/Storage/StorageConsumptionPart.cs @@ -0,0 +1,41 @@ +// Copyright © Datalust and contributors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Seq.Api.Model.Shared; + +namespace Seq.Api.Model.Diagnostics.Storage +{ + /// + /// Describes storage space consumed by the event store, for a range + /// of event timestamps. + /// + public class StorageConsumptionPart + { + /// + /// The range of timestamps covered by the result. + /// + public DateTimeRange Range { get; set; } + + /// + /// The duration of the timestamp interval covered by each result. + /// + public uint IntervalMinutes { get; set; } + + /// + /// A potentially-sparse rowset describing the storage space consumed + /// for a range of timestamp intervals. + /// + public RowsetPart Results { get; set; } + } +} diff --git a/src/Seq.Api/Model/License/LicenseEntity.cs b/src/Seq.Api/Model/License/LicenseEntity.cs index ea7aa61..0bdb65e 100644 --- a/src/Seq.Api/Model/License/LicenseEntity.cs +++ b/src/Seq.Api/Model/License/LicenseEntity.cs @@ -36,6 +36,11 @@ public class LicenseEntity : Entity /// public bool IsSingleUser { get; set; } + /// + /// If the license is a subscription, the subscription id. + /// + public string SubscriptionId { get; set; } + /// /// Information about the status of the license. /// @@ -56,5 +61,11 @@ public class LicenseEntity : Entity /// the license has no user limit. /// public int? LicensedUsers { get; set; } + + /// + /// If the license is for a subscription, automatically check datalust.co and + /// update the license when the subscription is renewed or tier changed. + /// + public bool AutomaticallyRefresh { get; set; } } } diff --git a/src/Seq.Api/Model/Shared/DateTimeRange.cs b/src/Seq.Api/Model/Shared/DateTimeRange.cs new file mode 100644 index 0000000..8790bdc --- /dev/null +++ b/src/Seq.Api/Model/Shared/DateTimeRange.cs @@ -0,0 +1,31 @@ +using System; + +namespace Seq.Api.Model.Shared +{ + /// + /// A range represented by a start and end . + /// + public readonly struct DateTimeRange + { + /// + /// The (inclusive) start of the range. + /// + public DateTime Start { get; } + + /// + /// The (exclusive) end of the range. + /// + public DateTime End { get; } + + /// + /// Construct a . + /// + /// The (inclusive) start of the range. + /// The (exclusive) end of the range. + public DateTimeRange(DateTime start, DateTime end) + { + Start = start; + End = end; + } + } +} \ No newline at end of file diff --git a/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs b/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs index a386bc0..644242c 100644 --- a/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs +++ b/src/Seq.Api/ResourceGroups/DiagnosticsResourceGroup.cs @@ -12,12 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Seq.Api.Model.Diagnostics; +using Seq.Api.Model.Diagnostics.Storage; using Seq.Api.Model.Inputs; +// ReSharper disable UnusedMember.Global + namespace Seq.Api.ResourceGroups { /// @@ -65,11 +69,38 @@ public async Task GetIngestionLogAsync(CancellationToken cancellationTok /// /// A allowing the operation to be canceled. /// The measurement to get. - /// + /// A timeseries showing the measurement over time. public async Task GetMeasurementTimeseriesAsync(string measurement, CancellationToken cancellationToken = default) { var parameters = new Dictionary{ ["measurement"] = measurement }; return await GroupGetAsync("Metric", parameters, cancellationToken); } + + /// + /// Report on storage space consumed by the event store across a range of timestamps. The returned range may be + /// extended to account for the resolution of the underlying data. + /// + /// The (inclusive) start of the range to report on. If omitted, the results will report from the + /// earliest stored data. The range start must land on a five-minute boundary. + /// The (exclusive) end of the range to report on. If omitted, the results will report from the + /// earliest stored data. The range must be a multiple of the interval size, or a whole number of days if + /// no interval is specified. + /// The bucket size to use. Must be a multiple of 5 minutes. Defaults to 1440 (one day). + /// A allowing the operation to be canceled. + /// Storage consumption information. + public async Task GetStorageConsumptionAsync( + DateTime? rangeStart, + DateTime? rangeEnd, + int? intervalMinutes, + CancellationToken cancellationToken = default) + { + var parameters = new Dictionary + { + ["rangeStart"] = rangeStart, + ["rangeEnd"] = rangeEnd, + ["intervalMinutes"] = intervalMinutes + }; + return await GroupGetAsync("Storage", parameters, cancellationToken); + } } } diff --git a/src/Seq.Api/Seq.Api.csproj b/src/Seq.Api/Seq.Api.csproj index 0de28ea..b20e2a9 100644 --- a/src/Seq.Api/Seq.Api.csproj +++ b/src/Seq.Api/Seq.Api.csproj @@ -1,7 +1,7 @@ Client library for the Seq HTTP API. - 2020.1.1 + 2020.4.0 Datalust;Contributors netstandard2.0 true @@ -14,7 +14,7 @@ 8 - +