Skip to content

[WIP] manage cluster capacity policy via KST #106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

ashleyvansp
Copy link

No description provided.

@Copilot Copilot AI review requested due to automatic review settings June 23, 2025 20:29
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for managing Kusto cluster capacity policies via KST by adding a new model, loader, and writer, and wiring them into the schema handler and database factory. It also updates JSON serialization to omit null values.

  • Define ClusterCapacityPolicy model with JSON serialization and script generation
  • Implement loader (ClusterCapacityPolicyLoader) and writer (ClusterCapacityPolicyWriter)
  • Wire capacity policy handling into KustoDatabaseHandlerFactory and KustoSchemaHandler

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Parser/KustoWriter/ClusterCapacityPolicyWriter.cs Writes .alter-merge cluster policy capacity commands
Parser/KustoLoader/ClusterCapacityPolicyLoader.cs Loads existing cluster capacity policy via .show query
Parser/KustoDatabaseHandlerFactory.cs Adds ClusterCapacityPolicyLoader and writer to factory
Model/Clusters.cs Adds CapacityPolicy property to clusters config
Model/ClusterCapacityPolicy.cs Defines capacity policy model and script creation
KustoSchemaHandler.cs Refactors handler to include capacity policy writer
Helpers/Serialization.cs Ignores nulls in JSON serialization
Tests/DemoData/.../partial-cluster-policy.yml Adds partial policy sample for tests
Tests/DemoData/.../comprehensive-cluster-policy.yml Adds full policy sample for tests
KustoSchemaTools.Tests/ClusterCapacityPolicyTests.cs Tests capacity policy loading, serialization, and script
Comments suppressed due to low confidence (2)

KustoSchemaTools.Tests/ClusterCapacityPolicyTests.cs:1

  • Missing using Xunit; and using System.IO; directives, which are required for the [Fact] attribute and for Path/File usage in this test file.
using KustoSchemaTools.Helpers;

KustoSchemaTools/Parser/KustoLoader/ClusterCapacityPolicyLoader.cs:24

  • The deserialized capacityPolicy is not stored on the database model, so the existing policy won't be tracked for comparison. Consider assigning it to database.CapacityPolicy.
                    var capacityPolicy = JsonConvert.DeserializeObject<ClusterCapacityPolicy>(capacityPolicyData);

private IDatabaseHandler<T> CreateDatabaseHandlerWithCapacityPolicy(string clusterUrl, string databaseName, ClusterCapacityPolicy? capacityPolicy)
{
// Create a logger - in a real application this would come from DI
var loggerFactory = LoggerFactory.Create(builder => { });
Copy link
Preview

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Instantiating a new LoggerFactory on each call is expensive; consider reusing a shared ILoggerFactory or injecting it once to reduce allocations.

Copilot uses AI. Check for mistakes.

// For now, we don't need to store it as we're only applying changes
}
}
catch (Exception)
Copy link
Preview

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Catching a broad Exception without any logging may hide underlying issues during load; consider logging a warning with exception details.

Copilot uses AI. Check for mistakes.

Comment on lines 55 to 56
return new KustoDatabaseHandlerFactory<T>(logger)
.WithReader<KustoDatabasePrincipalLoader>()
Copy link
Preview

Copilot AI Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The reader/writer setup chain is duplicated between CreateDefault and CreateDatabaseHandlerWithCapacityPolicy; extract into a shared helper to adhere to DRY principles.

Suggested change
return new KustoDatabaseHandlerFactory<T>(logger)
.WithReader<KustoDatabasePrincipalLoader>()
var factory = new KustoDatabaseHandlerFactory<T>(logger);
factory.AddDefaultReadersAndWriters();
return factory.Create(cluster, database);
}
private void AddDefaultReadersAndWriters()
{
WithReader<KustoDatabasePrincipalLoader>()

Copilot uses AI. Check for mistakes.

var diagnostics = parsedScript.GetDiagnostics();
if (diagnostics.Any())
{
Console.WriteLine($"Generated script: {diagnostics[0]}");

Check warning

Code scanning / CodeQL

Use of default ToString() Warning

Default 'ToString()':
Diagnostic
inherits 'ToString()' from 'Object', and so is not suitable for printing.

Copilot Autofix

AI about 22 hours ago

To fix the issue, the Diagnostic class (or its base class) should override the ToString() method to provide a meaningful string representation of diagnostic information. This could include details such as the diagnostic message, severity, and location. Since the definition of the Diagnostic class is not provided, we assume it is part of the Kusto.Language namespace or another external library. If modifying the Diagnostic class is not possible, an alternative is to explicitly format the diagnostic information in the ToUpdateScript method before printing it.


Suggested changeset 1
KustoSchemaTools/Model/ClusterCapacityPolicy.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/KustoSchemaTools/Model/ClusterCapacityPolicy.cs b/KustoSchemaTools/Model/ClusterCapacityPolicy.cs
--- a/KustoSchemaTools/Model/ClusterCapacityPolicy.cs
+++ b/KustoSchemaTools/Model/ClusterCapacityPolicy.cs
@@ -79,4 +79,4 @@
             {
-                Console.WriteLine($"Generated script: {diagnostics[0]}");
-
+                var diagnosticMessage = diagnostics[0].ToString() ?? "Unknown diagnostic";
+                Console.WriteLine($"Generated script: {diagnosticMessage}");
             }
EOF
@@ -79,4 +79,4 @@
{
Console.WriteLine($"Generated script: {diagnostics[0]}");

var diagnosticMessage = diagnostics[0].ToString() ?? "Unknown diagnostic";
Console.WriteLine($"Generated script: {diagnosticMessage}");
}
Copilot is powered by AI and may make mistakes. Always verify output.

// Asserts that there is exactly one property change detected.
// Because a nested property changed, the top-level property containing it is marked as changed.
var propertyChange = Assert.Single(policyChange.PropertyChanges);

Check warning

Code scanning / CodeQL

Dereferenced variable may be null Warning test

Variable
policyChange
may be null at this access because of
this
assignment.

Copilot Autofix

AI about 22 hours ago

To fix the issue, we need to ensure that policyChange is not null before accessing its PropertyChanges property. This can be achieved by adding a null check after the cast. If policyChange is null, the test should fail with an appropriate assertion message, as this would indicate an unexpected test setup or behavior.


Suggested changeset 1
KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs b/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
--- a/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
+++ b/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
@@ -51,2 +51,6 @@
             Assert.NotNull(policyChange);
+            if (policyChange == null)
+            {
+                Assert.Fail("The change in changeSet.Changes is not of type PolicyChange<ClusterCapacityPolicy>.");
+            }
 
EOF
@@ -51,2 +51,6 @@
Assert.NotNull(policyChange);
if (policyChange == null)
{
Assert.Fail("The change in changeSet.Changes is not of type PolicyChange<ClusterCapacityPolicy>.");
}

Copilot is powered by AI and may make mistakes. Always verify output.
// Assert
var policyChange = Assert.Single(changeSet.Changes) as PolicyChange<ClusterCapacityPolicy>;
Assert.NotNull(policyChange);
Assert.Equal(2, policyChange.PropertyChanges.Count);

Check warning

Code scanning / CodeQL

Dereferenced variable may be null Warning test

Variable
policyChange
may be null at this access because of
this
assignment.

Copilot Autofix

AI about 22 hours ago

To fix the issue, we need to ensure that policyChange is not null before dereferencing it. This can be achieved by adding an explicit null check after the assignment. If policyChange is null, the test should fail with a meaningful assertion message. This approach ensures that the test does not proceed with invalid data and avoids a potential NullReferenceException.

The changes will be made in the GenerateChanges_WithMultiplePropertyChanges_ShouldDetectAllChanges test method in the file KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs.


Suggested changeset 1
KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs b/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
--- a/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
+++ b/KustoSchemaTools.Tests/Changes/ClusterChangesTest.cs
@@ -78,2 +78,6 @@
             Assert.NotNull(policyChange);
+            if (policyChange == null)
+            {
+                Assert.Fail("Expected a PolicyChange<ClusterCapacityPolicy> but got null.");
+            }
             Assert.Equal(2, policyChange.PropertyChanges.Count);
EOF
@@ -78,2 +78,6 @@
Assert.NotNull(policyChange);
if (policyChange == null)
{
Assert.Fail("Expected a PolicyChange<ClusterCapacityPolicy> but got null.");
}
Assert.Equal(2, policyChange.PropertyChanges.Count);
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +42 to +45
catch (System.Exception ex)
{
_logger.LogError(ex, "Failed to load cluster capacity policy.");
}

Check notice

Code scanning / CodeQL

Generic catch clause Note

Generic catch clause.

Copilot Autofix

AI about 18 hours ago

To fix the issue, we will replace the generic catch (System.Exception ex) block with specific exception types that are relevant to the operation being performed. In this case:

  1. The ExecuteControlCommandAsync method might throw exceptions related to Kusto client operations, such as Kusto.Data.Exceptions.KustoClientException or Kusto.Data.Exceptions.KustoServiceException.
  2. The JsonConvert.DeserializeObject method might throw a JsonException if the JSON is invalid.

We will add separate catch blocks for these exceptions and log appropriate error messages for each. Any other unexpected exceptions will not be caught and will propagate, ensuring they are not silently ignored.


Suggested changeset 1
KustoSchemaTools/Parser/KustoClusterHandler.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/KustoSchemaTools/Parser/KustoClusterHandler.cs b/KustoSchemaTools/Parser/KustoClusterHandler.cs
--- a/KustoSchemaTools/Parser/KustoClusterHandler.cs
+++ b/KustoSchemaTools/Parser/KustoClusterHandler.cs
@@ -41,5 +41,13 @@
             }
-            catch (System.Exception ex)
+            catch (Kusto.Data.Exceptions.KustoClientException ex)
             {
-                _logger.LogError(ex, "Failed to load cluster capacity policy.");
+                _logger.LogError(ex, "Kusto client error occurred while loading cluster capacity policy.");
+            }
+            catch (Kusto.Data.Exceptions.KustoServiceException ex)
+            {
+                _logger.LogError(ex, "Kusto service error occurred while loading cluster capacity policy.");
+            }
+            catch (Newtonsoft.Json.JsonException ex)
+            {
+                _logger.LogError(ex, "JSON deserialization error occurred while parsing cluster capacity policy.");
             }
EOF
@@ -41,5 +41,13 @@
}
catch (System.Exception ex)
catch (Kusto.Data.Exceptions.KustoClientException ex)
{
_logger.LogError(ex, "Failed to load cluster capacity policy.");
_logger.LogError(ex, "Kusto client error occurred while loading cluster capacity policy.");
}
catch (Kusto.Data.Exceptions.KustoServiceException ex)
{
_logger.LogError(ex, "Kusto service error occurred while loading cluster capacity policy.");
}
catch (Newtonsoft.Json.JsonException ex)
{
_logger.LogError(ex, "JSON deserialization error occurred while parsing cluster capacity policy.");
}
Copilot is powered by AI and may make mistakes. Always verify output.
public async Task LoadAsync_ValidYamlFile_ReturnsClustersList()
{
// Arrange
var testFilePath = Path.Combine("DemoData", "ClusterScopedChanges", "multipleClusters.yml");

Check notice

Code scanning / CodeQL

Call to System.IO.Path.Combine Note test

Call to 'System.IO.Path.Combine'.

Copilot Autofix

AI about 14 hours ago

To fix the issue, replace the call to Path.Combine with Path.Join. The Path.Join method is designed to concatenate paths without treating absolute paths differently, making it a safer alternative in this context. The change will involve modifying line 17 to use Path.Join instead of Path.Combine. No additional imports or dependencies are required, as Path.Join is part of the System.IO namespace.

Suggested changeset 1
KustoSchemaTools.Tests/Parser/YamlClusterHandlerTests.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/KustoSchemaTools.Tests/Parser/YamlClusterHandlerTests.cs b/KustoSchemaTools.Tests/Parser/YamlClusterHandlerTests.cs
--- a/KustoSchemaTools.Tests/Parser/YamlClusterHandlerTests.cs
+++ b/KustoSchemaTools.Tests/Parser/YamlClusterHandlerTests.cs
@@ -16,3 +16,3 @@
             // Arrange
-            var testFilePath = Path.Combine("DemoData", "ClusterScopedChanges", "multipleClusters.yml");
+            var testFilePath = Path.Join("DemoData", "ClusterScopedChanges", "multipleClusters.yml");
             var handler = new YamlClusterHandler(testFilePath);
EOF
@@ -16,3 +16,3 @@
// Arrange
var testFilePath = Path.Combine("DemoData", "ClusterScopedChanges", "multipleClusters.yml");
var testFilePath = Path.Join("DemoData", "ClusterScopedChanges", "multipleClusters.yml");
var handler = new YamlClusterHandler(testFilePath);
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant