Skip to content

SQL Data masking cmdlets to stop using RuleId #1153

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

Merged
merged 2 commits into from
Oct 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ protected override void SetupManagementClients()
helper.SetupSomeOfManagementClients(sqlCSMClient, storageClient, storageV2Client, resourcesClient, authorizationClient);
}

[Fact(Skip = "PSGet: TODO fix by moving SM specific logic to test setup")] [Trait(Category.AcceptanceType, Category.Sql)]
[Fact(Skip = "PSGet: TODO fix by moving SM specific logic to test setup")]
[Trait(Category.AcceptanceType, Category.Sql)]
public void TestAuditingDatabaseUpdatePolicyWithStorage()
{
RunPowerShellTest("Test-AuditingDatabaseUpdatePolicyWithStorage");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void TestDatabaseDataMaskingTextRuleLifecycle()
RunPowerShellTest("Test-DatabaseDataMaskingTextRuleLifecycle");
}

[Fact]
[Fact(Skip = "Waiting for database structure validation")]
[Trait(Category.AcceptanceType, Category.BVT)]
public void TestDatabaseDataMaskingRuleCreationFailures()
{
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions src/ResourceManager/Sql/Commands.Sql/Common/AzureSqlCmdletBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ internal AzureSqlCmdletBase()
/// <returns>An initialized and ready to use ModelAdapter object</returns>
protected abstract A InitModelAdapter(AzureSubscription subscription);

/// <summary>
/// Transforms the given model object to be an object that is written out
/// </summary>
/// <param name="model">The about to be written model object</param>
/// <returns>The prepared object to be written out</returns>
protected virtual object TransformModelToOutputObject(M model)
{
return model;
}

/// <summary>
/// Executes the cmdlet
/// </summary>
Expand All @@ -99,14 +109,14 @@ protected override void ProcessRecord()
{
if (WriteResult())
{
this.WriteObject(responseModel, true);
this.WriteObject(TransformModelToOutputObject(responseModel), true);
}
}
else
{
if (WriteResult())
{
this.WriteObject(updatedModel);
this.WriteObject(TransformModelToOutputObject(updatedModel));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@ namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
/// </summary>
public abstract class BuildAzureSqlDatabaseDataMaskingRule : SqlDatabaseDataMaskingRuleCmdletBase
{
/// <summary>
/// Gets or sets the schema name
/// </summary>
public virtual string SchemaName { get; set; }

/// <summary>
/// Gets or sets the table name
/// </summary>
public virtual string TableName { get; set; }

/// <summary>
/// Gets or sets the column name
/// </summary>
public virtual string ColumnName { get; set; }

/// <summary>
/// Gets or sets the masking function - the definition of this property as a cmdlet parameter is done in the subclasses
/// </summary>
Expand Down Expand Up @@ -91,12 +76,7 @@ public abstract class BuildAzureSqlDatabaseDataMaskingRule : SqlDatabaseDataMask
/// <param name="model">A model object</param>
protected override IEnumerable<DatabaseDataMaskingRuleModel> ApplyUserInputToModel(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
string errorMessage = ValidateRuleTarget(rules);
if (string.IsNullOrEmpty(errorMessage))
{
errorMessage = ValidateOperation(rules);
}

string errorMessage = ValidateOperation(rules);
if(!string.IsNullOrEmpty(errorMessage))
{
throw new Exception(errorMessage);
Expand All @@ -106,20 +86,6 @@ protected override IEnumerable<DatabaseDataMaskingRuleModel> ApplyUserInputToMod
return UpdateRuleList(rules, rule);
}

/// <summary>
/// Validation that the rule's target is set properly to be either a table and column for which there's no other rule, or an alias for which there's no other rule.
/// </summary>
/// <param name="rules">The data masking rules of the current database</param>
/// <returns>A string containing error message or null in case all is fine</returns>
protected string ValidateRuleTarget(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
if (rules.Any(r => r.TableName == TableName && r.ColumnName == ColumnName && r.RuleId != RuleId))
{
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.DataMaskingTableAndColumnUsedError, TableName, ColumnName);
}
return null;
}

/// <summary>
/// Update the rule this cmdlet is operating on based on the values provided by the user
/// </summary>
Expand Down Expand Up @@ -254,7 +220,7 @@ private MaskingFunction ModelizeMaskingFunction()
/// <param name="model">The model object with the data to be sent to the REST endpoints</param>
protected override IEnumerable<DatabaseDataMaskingRuleModel> PersistChanges(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
ModelAdapter.SetDatabaseDataMaskingRule(rules.First(r => r.RuleId == RuleId), clientRequestId);
ModelAdapter.SetDatabaseDataMaskingRule(rules.First(IsModelOfRule), clientRequestId);
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Commands.Sql.DataMasking.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;

namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
Expand All @@ -23,13 +25,37 @@ namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
/// </summary>
[Cmdlet(VerbsCommon.Get, "AzureRmSqlDatabaseDataMaskingRule"), OutputType(typeof(IEnumerable<DatabaseDataMaskingRuleModel>))]
public class GetAzureSqlDatabaseDataMaskingRule : SqlDatabaseDataMaskingRuleCmdletBase
{
{
/// <summary>
/// Gets or sets the id of the rule use, if not provided then the list of rules for this DB is returned
/// Gets or sets the schema name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "Data Masking rule Id.")]
public override string RuleId { get; set; } // intentionally overiding to make this property non mandatory (thus allow a LIST call)
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The schema name.")]
[ValidateNotNullOrEmpty]
public override string SchemaName { get; set; }

/// <summary>
/// Gets or sets the table name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The table name.")]
[ValidateNotNullOrEmpty]
public override string TableName { get; set; }

/// <summary>
/// Gets or sets the column name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The column name.")]
[ValidateNotNullOrEmpty]
public override string ColumnName { get; set; }

protected override object TransformModelToOutputObject(IEnumerable<DatabaseDataMaskingRuleModel> model)
{
Predicate<DatabaseDataMaskingRuleModel> colPred = (DatabaseDataMaskingRuleModel r) => { return string.IsNullOrEmpty(ColumnName) ? true : r.ColumnName == ColumnName; };
Predicate<DatabaseDataMaskingRuleModel> tablePred = (DatabaseDataMaskingRuleModel r) => { return string.IsNullOrEmpty(TableName) ? true : r.TableName == TableName; };
Predicate<DatabaseDataMaskingRuleModel> schemaPred = (DatabaseDataMaskingRuleModel r) => { return string.IsNullOrEmpty(SchemaName) ? true : r.SchemaName == SchemaName; };
return model.Where(r => { return colPred(r) && tablePred(r) && schemaPred(r); }).ToList();
}


/// <summary>
/// No sending is needed as this is a Get cmdlet
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,6 @@ namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
[Cmdlet(VerbsCommon.New, "AzureRmSqlDatabaseDataMaskingRule")]
public class NewAzureSqlDatabaseDataMaskingRule : BuildAzureSqlDatabaseDataMaskingRule
{
/// <summary>
/// Gets or sets the column name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The column name.")]
[ValidateNotNullOrEmpty]
public override string ColumnName { get; set; }

/// <summary>
/// Gets or sets the schema name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The schema name.")]
[ValidateNotNullOrEmpty]
public override string SchemaName { get; set; }

/// <summary>
/// Gets or sets the table name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The table name.")]
[ValidateNotNullOrEmpty]
public override string TableName { get; set; }

/// <summary>
/// Gets or sets the masking function
/// </summary>
Expand All @@ -65,7 +44,7 @@ public class NewAzureSqlDatabaseDataMaskingRule : BuildAzureSqlDatabaseDataMaski
/// <returns>A model object</returns>
protected override IEnumerable<DatabaseDataMaskingRuleModel> GetEntity()
{
return ModelAdapter.GetDatabaseDataMaskingRule(ResourceGroupName, ServerName, DatabaseName, clientRequestId);
return ModelAdapter.GetDatabaseDataMaskingRules(ResourceGroupName, ServerName, DatabaseName, clientRequestId);
}

/// <summary>
Expand All @@ -75,15 +54,9 @@ protected override IEnumerable<DatabaseDataMaskingRuleModel> GetEntity()
/// <returns>An error message or null if all is fine</returns>
protected override string ValidateOperation(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
var ruleIdRegex = new Regex("^[^/\\\\#+=<>*%&:?]*[^/\\\\#+=<>*%&:?.]$");

if (!ruleIdRegex.IsMatch(RuleId)) // an invalid rule name
{
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.NewDataMaskingRuleIdIsNotValid, RuleId);
}
if(rules.Any(r=> r.RuleId == RuleId))
if (rules.Any(IsModelOfRule))
{
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.NewDataMaskingRuleIdAlreadyExistError, RuleId);
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.NewDataMaskingRuleIdAlreadyExistError, ColumnName, TableName, SchemaName);
}
return null;
}
Expand All @@ -99,7 +72,6 @@ protected override DatabaseDataMaskingRuleModel GetRule(IEnumerable<DatabaseData
rule.ResourceGroupName = ResourceGroupName;
rule.ServerName = ServerName;
rule.DatabaseName = DatabaseName;
rule.RuleId = RuleId;
return rule;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ public class RemoveAzureSqlDatabaseDataMaskingRule : SqlDatabaseDataMaskingRuleC
protected override IEnumerable<DatabaseDataMaskingRuleModel> PersistChanges(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
if (!Force.IsPresent && !ShouldProcess(
string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.RemoveDatabaseDataMaskingRuleDescription, RuleId, DatabaseName),
string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.RemoveDatabaseDataMaskingRuleWarning, RuleId, DatabaseName),
string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.RemoveDatabaseDataMaskingRuleDescription,
ColumnName, TableName, SchemaName, DatabaseName),
string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.RemoveDatabaseDataMaskingRuleWarning,
ColumnName, TableName, SchemaName, DatabaseName),
Microsoft.Azure.Commands.Sql.Properties.Resources.ShouldProcessCaption))
{
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,6 @@ namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
[Cmdlet(VerbsCommon.Set, "AzureRmSqlDatabaseDataMaskingRule")]
public class SetAzureSqlDatabaseDataMaskingRule : BuildAzureSqlDatabaseDataMaskingRule
{

/// <summary>
/// Gets or sets the column name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The column name.")]
public override string ColumnName { get; set; }

/// <summary>
/// Gets or sets the table name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The table name.")]
public override string TableName { get; set; }

/// <summary>
/// Gets or sets the schema name
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The schema name.")]
public override string SchemaName { get; set; }

/// <summary>
/// Gets or sets the masking function
/// </summary>
Expand All @@ -62,9 +43,9 @@ public class SetAzureSqlDatabaseDataMaskingRule : BuildAzureSqlDatabaseDataMaski
/// <returns>An error message or null if all is fine</returns>
protected override string ValidateOperation(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
if(!rules.Any(r=> r.RuleId == RuleId))
if (!rules.Any(IsModelOfRule))
{
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.SetDataMaskingRuleIdDoesNotExistError, RuleId);
return string.Format(CultureInfo.InvariantCulture, Microsoft.Azure.Commands.Sql.Properties.Resources.SetDataMaskingRuleIdDoesNotExistError, SchemaName, TableName, ColumnName);
}
return null;
}
Expand All @@ -75,8 +56,8 @@ protected override string ValidateOperation(IEnumerable<DatabaseDataMaskingRuleM
/// <param name="rules">The database's data masking rules</param>
/// <returns>A data masking rule object, initialized for the user provided rule identity</returns>
protected override DatabaseDataMaskingRuleModel GetRule(IEnumerable<DatabaseDataMaskingRuleModel> rules)
{
return rules.First(r=> r.RuleId == RuleId);
{
return rules.First(IsModelOfRule);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,49 @@ namespace Microsoft.Azure.Commands.Sql.DataMasking.Cmdlet
public abstract class SqlDatabaseDataMaskingRuleCmdletBase : AzureSqlDatabaseCmdletBase<IEnumerable<DatabaseDataMaskingRuleModel>, SqlDataMaskingAdapter>
{
/// <summary>
/// Gets or sets the id of the rule use.
/// Gets or sets the schema name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Data Masking rule Id.")]
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The schema name.")]
[ValidateNotNullOrEmpty]
public virtual string RuleId { get; set; }
public virtual string SchemaName { get; set; }

/// <summary>
/// Gets or sets the table name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The table name.")]
[ValidateNotNullOrEmpty]
public virtual string TableName { get; set; }

/// <summary>
/// Gets or sets the column name
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The column name.")]
[ValidateNotNullOrEmpty]
public virtual string ColumnName { get; set; }

/// <summary>
/// Checks whether the model of the current cmdlet is the same as the model of the given rule
/// </summary>
protected bool IsModelOfRule(BaseDataMaskingRuleModel rule)
{
return rule.ColumnName == ColumnName && rule.TableName == TableName && rule.SchemaName == SchemaName;
}

/// <summary>
/// The model is a list of rules. This method would return the specific rule that was updated
/// </summary>
protected override object TransformModelToOutputObject(IEnumerable<DatabaseDataMaskingRuleModel> model)
{
return model.FirstOrDefault(IsModelOfRule);
}

/// <summary>
/// Provides the model element that this cmdlet operates on
/// </summary>
/// <returns>A model object</returns>
protected override IEnumerable<DatabaseDataMaskingRuleModel> GetEntity()
{
return ModelAdapter.GetDatabaseDataMaskingRule(ResourceGroupName, ServerName, DatabaseName, clientRequestId, RuleId);
return ModelAdapter.GetDatabaseDataMaskingRules(ResourceGroupName, ServerName, DatabaseName, clientRequestId);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ public class BaseDataMaskingRuleModel
/// </summary>
public string ServerName { get; set; }

/// <summary>
/// Gets or sets the rule id
/// </summary>
public string RuleId { get; set; }

/// <summary>
/// Gets or sets the name of the chema that contains the table on which the rule operates on
/// </summary>
Expand Down
Loading