- Added ApiClientModel and ApiTokenModel for managing API clients and tokens. - Introduced ConfigurationDefinitionModel and ConfigurationValueModel for configuration management. - Created CredentialSecretModel for storing credential secrets. - Developed DeploymentArtifactModel and DeploymentBatchModel for deployment management. - Enhanced DeploymentTargetModel and DeploymentTemplateSelectionModel to support template revisions. - Added TemplateRevisionModel and TemplateVersionModel for versioning templates. - Implemented ApiClientSecretHasher for secure secret hashing. - Created ApiTokenService for generating and validating JWT tokens. - Updated QueueJobService to handle deployment requests with artifacts. - Configured authentication settings in appsettings.json for JWT and Negotiate authentication.
736 lines
49 KiB
C#
736 lines
49 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.SelfService.Portal.Core.API.Models;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Microsoft.SelfService.Portal.Core.API.Services;
|
|
|
|
namespace Microsoft.SelfService.Portal.Core.API.Context
|
|
{
|
|
internal static partial class DemoData
|
|
{
|
|
private static readonly DateTime Timestamp = new(2026, 7, 7, 0, 0, 0, DateTimeKind.Utc);
|
|
private const string Owner = "DemoSeed";
|
|
|
|
internal static readonly Guid EnvironmentContosoTestId = Guid.Parse("10000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid EnvironmentContosoProdId = Guid.Parse("10000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid EnvironmentM365Id = Guid.Parse("10000000-0000-0000-0000-000000000003");
|
|
|
|
internal static readonly Guid DomainCentralId = Guid.Parse("20000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DomainResourceId = Guid.Parse("20000000-0000-0000-0000-000000000002");
|
|
|
|
internal static readonly Guid VmDc01Id = Guid.Parse("30000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid VmDc02Id = Guid.Parse("30000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid VmSql01Id = Guid.Parse("30000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid VmSp01Id = Guid.Parse("30000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid VmSp02Id = Guid.Parse("30000000-0000-0000-0000-000000000005");
|
|
internal static readonly Guid TargetM365TenantId = Guid.Parse("30000000-0000-0000-0000-000000000006");
|
|
internal static readonly Guid TargetTeamsPolicyScopeId = Guid.Parse("30000000-0000-0000-0000-000000000007");
|
|
internal static readonly Guid TargetBgwSp01Id = Guid.Parse("30000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid TargetBgwSp02Id = Guid.Parse("30000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid TargetBgwSp03Id = Guid.Parse("30000000-0000-0000-0000-000000000103");
|
|
|
|
internal static readonly Guid ServiceActiveDirectoryId = Guid.Parse("40000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid ServiceSqlServerId = Guid.Parse("40000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid ServiceSharePointId = Guid.Parse("40000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid ServiceTeamsId = Guid.Parse("40000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid ServiceConfigurationDataId = Guid.Parse("40000000-0000-0000-0000-000000000101");
|
|
|
|
internal static readonly Guid CategoryActiveDirectoryId = Guid.Parse("50000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid CategorySqlServerId = Guid.Parse("50000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid CategorySharePointId = Guid.Parse("50000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid CategoryTeamsId = Guid.Parse("50000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid CategoryBgwMergeTemplatesId = Guid.Parse("50000000-0000-0000-0000-000000000101");
|
|
|
|
internal static readonly Guid RuleStandardId = Guid.Parse("60000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid RuleStepValidateId = Guid.Parse("60000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid RuleStepApproveId = Guid.Parse("60000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid RuleStepDeployId = Guid.Parse("60000000-0000-0000-0000-000000000103");
|
|
|
|
internal static readonly Guid TemplateActiveDirectoryId = Guid.Parse("70000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid TemplateSqlServerId = Guid.Parse("70000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid TemplateSharePointId = Guid.Parse("70000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid TemplateTeamsId = Guid.Parse("70000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid TemplateBgwEnvironmentTestId = Guid.Parse("70000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid TemplateBgwDomainContosoId = Guid.Parse("70000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid TemplateBgwSharePointContosoId = Guid.Parse("70000000-0000-0000-0000-000000000103");
|
|
internal static readonly Guid TemplateBgwStageInstallId = Guid.Parse("70000000-0000-0000-0000-000000000104");
|
|
|
|
internal static readonly Guid TemplateActiveDirectoryVersionId = Guid.Parse("71000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid TemplateSqlServerVersionId = Guid.Parse("71000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid TemplateSharePointVersionId = Guid.Parse("71000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid TemplateTeamsVersionId = Guid.Parse("71000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid TemplateBgwEnvironmentTestVersionId = Guid.Parse("71000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid TemplateBgwDomainContosoVersionId = Guid.Parse("71000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid TemplateBgwSharePointContosoVersionId = Guid.Parse("71000000-0000-0000-0000-000000000103");
|
|
internal static readonly Guid TemplateBgwStageInstallVersionId = Guid.Parse("71000000-0000-0000-0000-000000000104");
|
|
|
|
internal static readonly Guid TemplateActiveDirectoryRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid TemplateSqlServerRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid TemplateSharePointRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid TemplateTeamsRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid TemplateBgwEnvironmentTestRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid TemplateBgwDomainContosoRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid TemplateBgwSharePointContosoRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000103");
|
|
internal static readonly Guid TemplateBgwStageInstallRevisionId = Guid.Parse("72000000-0000-0000-0000-000000000104");
|
|
|
|
internal static readonly Guid DeploymentBatchSharePointId = Guid.Parse("80000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DeploymentBatchBgwMergeId = Guid.Parse("80000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid DeploymentSp01Id = Guid.Parse("81000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DeploymentSp02Id = Guid.Parse("81000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid DeploymentBgwSp01Id = Guid.Parse("81000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid DeploymentBgwSp02Id = Guid.Parse("81000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid DeploymentBgwSp03Id = Guid.Parse("81000000-0000-0000-0000-000000000103");
|
|
internal static readonly Guid DeploymentSharePointTemplateSelectionId = Guid.Parse("82000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DeploymentBgwEnvironmentSelectionId = Guid.Parse("82000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid DeploymentBgwDomainSelectionId = Guid.Parse("82000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid DeploymentBgwSharePointSelectionId = Guid.Parse("82000000-0000-0000-0000-000000000103");
|
|
internal static readonly Guid DeploymentBgwStageSelectionId = Guid.Parse("82000000-0000-0000-0000-000000000104");
|
|
internal static readonly Guid DeploymentParameterDatabasePrefixId = Guid.Parse("83000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DeploymentParameterFarmAccountId = Guid.Parse("83000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid DeploymentTargetSp01Id = Guid.Parse("84000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid DeploymentTargetSp02Id = Guid.Parse("84000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid DeploymentTargetBgwSp01Id = Guid.Parse("84000000-0000-0000-0000-000000000101");
|
|
internal static readonly Guid DeploymentTargetBgwSp02Id = Guid.Parse("84000000-0000-0000-0000-000000000102");
|
|
internal static readonly Guid DeploymentTargetBgwSp03Id = Guid.Parse("84000000-0000-0000-0000-000000000103");
|
|
|
|
internal static readonly Guid DeploymentArtifactBgwResolvedId = Guid.Parse("85000000-0000-0000-0000-000000000101");
|
|
|
|
internal static readonly Guid CredentialSharePointSetupId = Guid.Parse("90000000-0000-0000-0000-000000000001");
|
|
internal static readonly Guid CredentialSharePointFarmId = Guid.Parse("90000000-0000-0000-0000-000000000002");
|
|
internal static readonly Guid CredentialSharePointFarmPassphraseId = Guid.Parse("90000000-0000-0000-0000-000000000003");
|
|
internal static readonly Guid CredentialSharePointDefaultServiceId = Guid.Parse("90000000-0000-0000-0000-000000000004");
|
|
internal static readonly Guid CredentialSharePointSearchId = Guid.Parse("90000000-0000-0000-0000-000000000005");
|
|
internal static readonly Guid ApiClientDemoWorkerId = Guid.Parse("91000000-0000-0000-0000-000000000001");
|
|
|
|
internal static void Seed(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.Entity<EnvironmentModel>().HasData(Environments());
|
|
modelBuilder.Entity<DomainModel>().HasData(Domains());
|
|
modelBuilder.Entity<EnvironmentDomainsModel>().HasData(EnvironmentDomains());
|
|
modelBuilder.Entity<TargetModel>().HasData(Targets());
|
|
modelBuilder.Entity<ServiceModel>().HasData(Services());
|
|
modelBuilder.Entity<ServiceRoleDefinitionModel>().HasData(ServiceRoleDefinitions());
|
|
modelBuilder.Entity<TemplateCategoryModel>().HasData(TemplateCategories());
|
|
modelBuilder.Entity<DeploymentRuleModel>().HasData(DeploymentRules());
|
|
modelBuilder.Entity<DeploymentRuleStepModel>().HasData(DeploymentRuleSteps());
|
|
modelBuilder.Entity<TemplateModel>().HasData(Templates());
|
|
modelBuilder.Entity<TemplateVersionModel>().HasData(TemplateVersions());
|
|
modelBuilder.Entity<TemplateRevisionModel>().HasData(TemplateRevisions());
|
|
modelBuilder.Entity<ConfigurationDefinitionModel>().HasData(ConfigurationDefinitions());
|
|
modelBuilder.Entity<ConfigurationValueModel>().HasData(ConfigurationValues());
|
|
modelBuilder.Entity<DeploymentGroupModel>().HasData(DeploymentBatches());
|
|
modelBuilder.Entity<DeploymentModel>().HasData(Deployments());
|
|
modelBuilder.Entity<DeploymentTemplateSelectionModel>().HasData(DeploymentTemplateSelections());
|
|
modelBuilder.Entity<DeploymentParameterValueModel>().HasData(DeploymentParameterValues());
|
|
modelBuilder.Entity<DeploymentTargetAssignmentModel>().HasData(DeploymentTargetAssignments());
|
|
modelBuilder.Entity<DeploymentArtifactModel>().HasData(DeploymentArtifacts());
|
|
modelBuilder.Entity<CredentialSecretModel>().HasData(CredentialSecrets());
|
|
modelBuilder.Entity<ApiClientModel>().HasData(ApiClients());
|
|
}
|
|
|
|
private static object[] Environments() =>
|
|
[
|
|
Base(new EnvironmentModel { Id = EnvironmentContosoTestId, Name = "Contoso Test", EnvironmentType = EnvironmentStages.Test, HostingType = EnvironmentHostingTypes.OnPrem, MetadataJson = "{\"location\":\"Datacenter A\"}" }),
|
|
Base(new EnvironmentModel { Id = EnvironmentContosoProdId, Name = "Contoso Production", EnvironmentType = EnvironmentStages.Production, HostingType = EnvironmentHostingTypes.OnPrem, MetadataJson = "{\"location\":\"Datacenter A\"}" }),
|
|
Base(new EnvironmentModel { Id = EnvironmentM365Id, Name = "Contoso M365", EnvironmentType = EnvironmentStages.Production, HostingType = EnvironmentHostingTypes.M365Tenant, ProviderType = "Microsoft365", TenantId = "11111111-1111-1111-1111-111111111111", MetadataJson = "{\"tenant\":\"contoso.onmicrosoft.com\"}" })
|
|
];
|
|
|
|
private static object[] Domains() =>
|
|
[
|
|
Base(new DomainModel { Id = DomainCentralId, Name = "Central Management", FQDN = "corp.contoso.com", NetBIOS = "CONTOSO" }),
|
|
Base(new DomainModel { Id = DomainResourceId, Name = "Resource Domain", FQDN = "resource.contoso.com", NetBIOS = "RESOURCE" })
|
|
];
|
|
|
|
private static object[] EnvironmentDomains() =>
|
|
[
|
|
Junction(new EnvironmentDomainsModel { EnvironmentId = EnvironmentContosoTestId, DomainId = DomainCentralId }),
|
|
Junction(new EnvironmentDomainsModel { EnvironmentId = EnvironmentContosoProdId, DomainId = DomainCentralId }),
|
|
Junction(new EnvironmentDomainsModel { EnvironmentId = EnvironmentContosoProdId, DomainId = DomainResourceId })
|
|
];
|
|
|
|
private static object[] Targets() =>
|
|
[
|
|
Base(new TargetModel { Id = VmDc01Id, DomainID = DomainCentralId, Name = "CT-DC-01", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"DomainController\",\"environment\":\"Test\"}" }),
|
|
Base(new TargetModel { Id = VmDc02Id, DomainID = DomainCentralId, Name = "CT-DC-02", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"DomainController\",\"environment\":\"Production\"}" }),
|
|
Base(new TargetModel { Id = VmSql01Id, DomainID = DomainCentralId, Name = "CT-SQL-01", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SqlServer\",\"environment\":\"Test\"}" }),
|
|
Base(new TargetModel { Id = VmSp01Id, DomainID = DomainCentralId, Name = "CT-SHP-01", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SharePoint\",\"environment\":\"Test\"}" }),
|
|
Base(new TargetModel { Id = VmSp02Id, DomainID = DomainCentralId, Name = "CT-SHP-02", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SharePoint\",\"environment\":\"Test\"}" }),
|
|
Base(new TargetModel { Id = TargetM365TenantId, Name = "contoso.onmicrosoft.com", TargetType = "Tenant", ProviderType = "Microsoft365", ExternalId = "11111111-1111-1111-1111-111111111111", MetadataJson = "{\"environment\":\"Production\",\"workload\":\"M365\"}" }),
|
|
Base(new TargetModel { Id = TargetTeamsPolicyScopeId, Name = "Teams - Standard Users", TargetType = "PolicyScope", ProviderType = "Microsoft365", ExternalId = "Teams.StandardUsers", MetadataJson = "{\"workload\":\"Teams\",\"scope\":\"StandardUsers\"}" }),
|
|
Base(new TargetModel { Id = TargetBgwSp01Id, DomainID = DomainCentralId, Name = "CLD-SHP-01", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SharePoint\",\"environment\":\"Test\",\"source\":\"Test.Merge.ps1\"}" }),
|
|
Base(new TargetModel { Id = TargetBgwSp02Id, DomainID = DomainCentralId, Name = "CLD-SHP-02", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SharePoint\",\"environment\":\"Test\",\"source\":\"Test.Merge.ps1\"}" }),
|
|
Base(new TargetModel { Id = TargetBgwSp03Id, DomainID = DomainCentralId, Name = "CLD-SHP-03", TargetType = "VirtualMachine", ProviderType = "OnPrem", MetadataJson = "{\"role\":\"SharePoint\",\"environment\":\"Test\",\"source\":\"Test.Merge.ps1\"}" })
|
|
];
|
|
|
|
private static object[] Services() =>
|
|
[
|
|
Base(new ServiceModel { Id = ServiceActiveDirectoryId, Name = "Active Directory", Description = "On-premises directory and identity service.", IconKey = "network", IsCloudService = false }),
|
|
Base(new ServiceModel { Id = ServiceSqlServerId, Name = "SQL Server", Description = "Database platform for application workloads.", IconKey = "database", IsCloudService = false }),
|
|
Base(new ServiceModel { Id = ServiceSharePointId, Name = "SharePoint Server", Description = "Collaboration platform for on-premises workloads.", IconKey = "sharepoint", IsCloudService = false }),
|
|
Base(new ServiceModel { Id = ServiceTeamsId, Name = "Microsoft Teams", Description = "Cloud collaboration workload in Microsoft 365.", IconKey = "messages-square", IsCloudService = true }),
|
|
Base(new ServiceModel { Id = ServiceConfigurationDataId, Name = "DSC Configuration Data", Description = "Reusable configuration-data template building blocks for deployment composition.", IconKey = "braces", IsCloudService = false })
|
|
];
|
|
|
|
private static object[] ServiceRoleDefinitions() =>
|
|
[
|
|
Base(new ServiceRoleDefinitionModel { Id = Guid.Parse("41000000-0000-0000-0000-000000000001"), ServiceId = ServiceSharePointId, Key = "Farm", Name = "Farm", Description = "SharePoint farm role." }),
|
|
Base(new ServiceRoleDefinitionModel { Id = Guid.Parse("41000000-0000-0000-0000-000000000002"), ServiceId = ServiceSharePointId, Key = "WebFrontEnd", Name = "Web Front End", Description = "SharePoint web front-end role." }),
|
|
Base(new ServiceRoleDefinitionModel { Id = Guid.Parse("41000000-0000-0000-0000-000000000003"), ServiceId = ServiceSharePointId, Key = "Application", Name = "Application", Description = "SharePoint service application role." }),
|
|
Base(new ServiceRoleDefinitionModel { Id = Guid.Parse("41000000-0000-0000-0000-000000000004"), ServiceId = ServiceSqlServerId, Key = "Database", Name = "Database", Description = "SQL Server database role." })
|
|
];
|
|
|
|
private static object[] TemplateCategories() =>
|
|
[
|
|
Base(new TemplateCategoryModel { Id = CategoryActiveDirectoryId, ServiceId = ServiceActiveDirectoryId, Name = "Domain Services", Description = "Templates for domain controller and domain configuration.", Color = "#2563EB", IsActive = true }),
|
|
Base(new TemplateCategoryModel { Id = CategorySqlServerId, ServiceId = ServiceSqlServerId, Name = "Database Platform", Description = "Templates for SQL Server workloads.", Color = "#16A34A", IsActive = true }),
|
|
Base(new TemplateCategoryModel { Id = CategorySharePointId, ServiceId = ServiceSharePointId, Name = "Collaboration Farm", Description = "Templates for SharePoint Server farms.", Color = "#0F766E", IsActive = true }),
|
|
Base(new TemplateCategoryModel { Id = CategoryTeamsId, ServiceId = ServiceTeamsId, Name = "Teams Policies", Description = "Templates for Teams policy configuration.", Color = "#7C3AED", IsActive = true }),
|
|
Base(new TemplateCategoryModel { Id = CategoryBgwMergeTemplatesId, ServiceId = ServiceConfigurationDataId, Name = "Test.Merge.ps1 Templates", Description = "Materialized template building blocks from the BGW Test.Merge.ps1 scenario.", Color = "#2563EB", IsActive = true })
|
|
];
|
|
|
|
private static object[] DeploymentRules() =>
|
|
[
|
|
Base(new DeploymentRuleModel { Id = RuleStandardId, Name = "Standard Provisioning", Description = "Validate input, wait for approval, then provision targets.", IsActive = true })
|
|
];
|
|
|
|
private static object[] DeploymentRuleSteps() =>
|
|
[
|
|
Base(new DeploymentRuleStepModel { Id = RuleStepValidateId, DeploymentRuleId = RuleStandardId, SortOrder = 10, Name = "Validate configuration", StepType = QueueJobStepType.Provision, RequiresApproval = false, MetadataJson = "{\"action\":\"validate\"}" }),
|
|
Base(new DeploymentRuleStepModel { Id = RuleStepApproveId, DeploymentRuleId = RuleStandardId, SortOrder = 20, Name = "Approve deployment", StepType = QueueJobStepType.Approval, RequiresApproval = true, MetadataJson = "{\"approverGroup\":\"Platform Owners\"}" }),
|
|
Base(new DeploymentRuleStepModel { Id = RuleStepDeployId, DeploymentRuleId = RuleStandardId, SortOrder = 30, Name = "Provision workload", StepType = QueueJobStepType.Provision, RequiresApproval = false, MetadataJson = "{\"action\":\"deploy\"}" })
|
|
];
|
|
|
|
private static object[] Templates() =>
|
|
[
|
|
Base(new TemplateModel { Id = TemplateActiveDirectoryId, TemplateCategoryId = CategoryActiveDirectoryId, DeploymentRuleId = RuleStandardId, Name = "Contoso Active Directory Domain", Version = "1.0.0", Description = "Creates a reusable Active Directory domain baseline.", JSONData = ActiveDirectoryTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateSqlServerId, TemplateCategoryId = CategorySqlServerId, DeploymentRuleId = RuleStandardId, Name = "Contoso SQL Server", Version = "1.0.0", Description = "Creates a SQL Server baseline for application workloads.", JSONData = SqlServerTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateSharePointId, TemplateCategoryId = CategorySharePointId, DeploymentRuleId = RuleStandardId, Name = "Contoso SharePoint Server", Version = "1.0.0", Description = "Creates a SharePoint Server farm baseline.", JSONData = SharePointTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateTeamsId, TemplateCategoryId = CategoryTeamsId, DeploymentRuleId = RuleStandardId, Name = "Contoso Teams Policies", Version = "1.0.0", Description = "Creates a Microsoft Teams policy baseline.", JSONData = TeamsTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateBgwEnvironmentTestId, TemplateCategoryId = CategoryBgwMergeTemplatesId, DeploymentRuleId = RuleStandardId, Name = "BGW Environment Test", Version = "1.0.0", Description = "Materialized Environment/Test.psd1 template from Test.Merge.ps1.", JSONData = BgwEnvironmentTestTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateBgwDomainContosoId, TemplateCategoryId = CategoryBgwMergeTemplatesId, DeploymentRuleId = RuleStandardId, Name = "BGW Domain Contoso", Version = "1.0.0", Description = "Materialized Domain/Contoso.psd1 template from Test.Merge.ps1.", JSONData = BgwDomainContosoTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateBgwSharePointContosoId, TemplateCategoryId = CategoryBgwMergeTemplatesId, DeploymentRuleId = RuleStandardId, Name = "BGW SharePoint Contoso", Version = "1.0.0", Description = "Materialized Service/SharePoint/Contoso.psd1 template from Test.Merge.ps1.", JSONData = BgwSharePointContosoTemplateJson }),
|
|
Base(new TemplateModel { Id = TemplateBgwStageInstallId, TemplateCategoryId = CategoryBgwMergeTemplatesId, DeploymentRuleId = RuleStandardId, Name = "BGW Stage Install", Version = "1.0.0", Description = "Materialized Stage/Install.psd1 template from Test.Merge.ps1.", JSONData = BgwStageInstallTemplateJson })
|
|
];
|
|
|
|
private static object[] TemplateVersions() =>
|
|
[
|
|
TemplateVersion(TemplateActiveDirectoryVersionId, TemplateActiveDirectoryId, ActiveDirectoryTemplateJson),
|
|
TemplateVersion(TemplateSqlServerVersionId, TemplateSqlServerId, SqlServerTemplateJson),
|
|
TemplateVersion(TemplateSharePointVersionId, TemplateSharePointId, SharePointTemplateJson),
|
|
TemplateVersion(TemplateTeamsVersionId, TemplateTeamsId, TeamsTemplateJson),
|
|
TemplateVersion(TemplateBgwEnvironmentTestVersionId, TemplateBgwEnvironmentTestId, BgwEnvironmentTestTemplateJson),
|
|
TemplateVersion(TemplateBgwDomainContosoVersionId, TemplateBgwDomainContosoId, BgwDomainContosoTemplateJson),
|
|
TemplateVersion(TemplateBgwSharePointContosoVersionId, TemplateBgwSharePointContosoId, BgwSharePointContosoTemplateJson),
|
|
TemplateVersion(TemplateBgwStageInstallVersionId, TemplateBgwStageInstallId, BgwStageInstallTemplateJson)
|
|
];
|
|
|
|
private static object[] TemplateRevisions() =>
|
|
[
|
|
TemplateRevision(TemplateActiveDirectoryRevisionId, TemplateActiveDirectoryVersionId, ActiveDirectoryTemplateJson),
|
|
TemplateRevision(TemplateSqlServerRevisionId, TemplateSqlServerVersionId, SqlServerTemplateJson),
|
|
TemplateRevision(TemplateSharePointRevisionId, TemplateSharePointVersionId, SharePointTemplateJson),
|
|
TemplateRevision(TemplateTeamsRevisionId, TemplateTeamsVersionId, TeamsTemplateJson),
|
|
TemplateRevision(TemplateBgwEnvironmentTestRevisionId, TemplateBgwEnvironmentTestVersionId, BgwEnvironmentTestTemplateJson),
|
|
TemplateRevision(TemplateBgwDomainContosoRevisionId, TemplateBgwDomainContosoVersionId, BgwDomainContosoTemplateJson),
|
|
TemplateRevision(TemplateBgwSharePointContosoRevisionId, TemplateBgwSharePointContosoVersionId, BgwSharePointContosoTemplateJson),
|
|
TemplateRevision(TemplateBgwStageInstallRevisionId, TemplateBgwStageInstallVersionId, BgwStageInstallTemplateJson)
|
|
];
|
|
|
|
private static object[] DeploymentBatches() =>
|
|
[
|
|
Base(new DeploymentGroupModel { Id = DeploymentBatchSharePointId, TemplateId = TemplateSharePointId, DeploymentRuleId = RuleStandardId, Status = QueueJobStatus.Pending }),
|
|
Base(new DeploymentGroupModel { Id = DeploymentBatchBgwMergeId, TemplateId = TemplateBgwSharePointContosoId, DeploymentRuleId = RuleStandardId, Status = QueueJobStatus.Pending })
|
|
];
|
|
|
|
private static object[] Deployments() =>
|
|
[
|
|
Base(new DeploymentModel { Id = DeploymentSp01Id, DeploymentGroupId = DeploymentBatchSharePointId, TargetId = VmSp01Id, TemplateRevisionId = TemplateSharePointRevisionId, Status = QueueJobStatus.Pending, JSONData = "{\"role\":\"WebFrontEnd\"}" }),
|
|
Base(new DeploymentModel { Id = DeploymentSp02Id, DeploymentGroupId = DeploymentBatchSharePointId, TargetId = VmSp02Id, TemplateRevisionId = TemplateSharePointRevisionId, Status = QueueJobStatus.Pending, JSONData = "{\"role\":\"Application\"}" }),
|
|
Base(new DeploymentModel { Id = DeploymentBgwSp01Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp01Id, TemplateRevisionId = TemplateBgwSharePointContosoRevisionId, Status = QueueJobStatus.Pending, JSONData = "{\"role\":\"Node\"}" }),
|
|
Base(new DeploymentModel { Id = DeploymentBgwSp02Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp02Id, TemplateRevisionId = TemplateBgwSharePointContosoRevisionId, Status = QueueJobStatus.Pending, JSONData = "{\"role\":\"Node\"}" }),
|
|
Base(new DeploymentModel { Id = DeploymentBgwSp03Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp03Id, TemplateRevisionId = TemplateBgwSharePointContosoRevisionId, Status = QueueJobStatus.Pending, JSONData = "{\"role\":\"Node\"}" })
|
|
];
|
|
|
|
private static object[] DeploymentTemplateSelections() =>
|
|
[
|
|
Base(new DeploymentTemplateSelectionModel { Id = DeploymentSharePointTemplateSelectionId, DeploymentGroupId = DeploymentBatchSharePointId, TemplateVersionId = TemplateSharePointVersionId, TemplateRevisionId = TemplateSharePointRevisionId, TemplateRole = "Service", SortOrder = 10, Alias = "SharePoint" }),
|
|
Base(new DeploymentTemplateSelectionModel { Id = DeploymentBgwEnvironmentSelectionId, DeploymentGroupId = DeploymentBatchBgwMergeId, TemplateVersionId = TemplateBgwEnvironmentTestVersionId, TemplateRevisionId = TemplateBgwEnvironmentTestRevisionId, TemplateRole = "Environment", SortOrder = 10, Alias = "Environment-Test" }),
|
|
Base(new DeploymentTemplateSelectionModel { Id = DeploymentBgwDomainSelectionId, DeploymentGroupId = DeploymentBatchBgwMergeId, TemplateVersionId = TemplateBgwDomainContosoVersionId, TemplateRevisionId = TemplateBgwDomainContosoRevisionId, TemplateRole = "Domain", SortOrder = 20, Alias = "Domain-Contoso" }),
|
|
Base(new DeploymentTemplateSelectionModel { Id = DeploymentBgwSharePointSelectionId, DeploymentGroupId = DeploymentBatchBgwMergeId, TemplateVersionId = TemplateBgwSharePointContosoVersionId, TemplateRevisionId = TemplateBgwSharePointContosoRevisionId, TemplateRole = "Service", SortOrder = 30, Alias = "Service-SharePoint-Contoso" }),
|
|
Base(new DeploymentTemplateSelectionModel { Id = DeploymentBgwStageSelectionId, DeploymentGroupId = DeploymentBatchBgwMergeId, TemplateVersionId = TemplateBgwStageInstallVersionId, TemplateRevisionId = TemplateBgwStageInstallRevisionId, TemplateRole = "Stage", SortOrder = 40, Alias = "Stage-Install" })
|
|
];
|
|
|
|
private static object[] DeploymentParameterValues() =>
|
|
[
|
|
Base(new DeploymentParameterValueModel { Id = DeploymentParameterDatabasePrefixId, DeploymentGroupId = DeploymentBatchSharePointId, DeploymentTemplateSelectionId = DeploymentSharePointTemplateSelectionId, Name = "DatabasePrefix", ValueJson = "{\"value\":\"SharePoint_Contoso_Test\"}", IsOverride = true, IsSecretReference = false }),
|
|
Base(new DeploymentParameterValueModel { Id = DeploymentParameterFarmAccountId, DeploymentGroupId = DeploymentBatchSharePointId, DeploymentTemplateSelectionId = DeploymentSharePointTemplateSelectionId, Name = "FarmAccount", ValueJson = "{\"provider\":\"SecretManagement\",\"vault\":\"ContosoDemo\",\"name\":\"Windows/SharePoint/FarmAccount\"}", IsOverride = true, IsSecretReference = true })
|
|
];
|
|
|
|
private static object[] DeploymentTargetAssignments() =>
|
|
[
|
|
Base(new DeploymentTargetAssignmentModel { Id = DeploymentTargetSp01Id, DeploymentGroupId = DeploymentBatchSharePointId, TargetId = VmSp01Id, RoleKey = "WebFrontEnd", SortOrder = 10, NodeDataJson = "{\"nodeName\":\"CT-SHP-01\"}" }),
|
|
Base(new DeploymentTargetAssignmentModel { Id = DeploymentTargetSp02Id, DeploymentGroupId = DeploymentBatchSharePointId, TargetId = VmSp02Id, RoleKey = "Application", SortOrder = 20, NodeDataJson = "{\"nodeName\":\"CT-SHP-02\"}" }),
|
|
Base(new DeploymentTargetAssignmentModel { Id = DeploymentTargetBgwSp01Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp01Id, RoleKey = "Node", SortOrder = 10, NodeDataJson = "{\"nodeName\":\"CLD-SHP-01\",\"RunCentralAdministration\":true}" }),
|
|
Base(new DeploymentTargetAssignmentModel { Id = DeploymentTargetBgwSp02Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp02Id, RoleKey = "Node", SortOrder = 20, NodeDataJson = "{\"nodeName\":\"CLD-SHP-02\",\"RunCentralAdministration\":false}" }),
|
|
Base(new DeploymentTargetAssignmentModel { Id = DeploymentTargetBgwSp03Id, DeploymentGroupId = DeploymentBatchBgwMergeId, TargetId = TargetBgwSp03Id, RoleKey = "Node", SortOrder = 30, NodeDataJson = "{\"nodeName\":\"CLD-SHP-03\",\"RunCentralAdministration\":false}" })
|
|
];
|
|
|
|
private static object[] ConfigurationDefinitions()
|
|
{
|
|
return TemplateRevisionJsonDocuments()
|
|
.SelectMany(template => ExtractConfigurationDefinitions(template.RevisionId, template.JsonData))
|
|
.Select(definition => Base(definition))
|
|
.Cast<object>()
|
|
.ToArray();
|
|
}
|
|
|
|
private static object[] ConfigurationValues()
|
|
{
|
|
return TemplateRevisionJsonDocuments()
|
|
.SelectMany(template => ExtractConfigurationValues(template.RevisionId, template.JsonData))
|
|
.Select(value => Base(value))
|
|
.Cast<object>()
|
|
.ToArray();
|
|
}
|
|
|
|
private static object[] DeploymentArtifacts()
|
|
{
|
|
var deploymentJson = """
|
|
{
|
|
"metadata": {
|
|
"name": "Contoso-Test-SharePoint",
|
|
"deploymentId": "8f6c2c1a",
|
|
"source": "DemoData"
|
|
},
|
|
"parameters": {
|
|
"DatabasePrefix": "SharePoint_Contoso_Test"
|
|
},
|
|
"variables": {
|
|
"DatabasePrefix": "SharePoint_Contoso_Test",
|
|
"ServiceDbPrefix": "SharePoint_Contoso_Test_Services",
|
|
"ConfigDbName": "SharePoint_Contoso_Test_Farm_Config"
|
|
},
|
|
"resources": {
|
|
"AllNodes": [
|
|
{ "NodeName": "CLD-SHP-01", "RunCentralAdministration": true },
|
|
{ "NodeName": "CLD-SHP-02", "RunCentralAdministration": false },
|
|
{ "NodeName": "CLD-SHP-03", "RunCentralAdministration": false }
|
|
],
|
|
"NonNodeData": {
|
|
"LocalConfigurationManager": {
|
|
"ConfigurationMode": "ApplyOnly"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
|
|
var sourceSnapshotJson = BgwMergeSourceSnapshotJson();
|
|
|
|
return
|
|
[
|
|
Base(new DeploymentArtifactModel
|
|
{
|
|
Id = DeploymentArtifactBgwResolvedId,
|
|
DeploymentGroupId = DeploymentBatchBgwMergeId,
|
|
ArtifactType = DeploymentArtifactTypes.ResolvedConfigurationData,
|
|
Status = QueueJobStatus.Pending,
|
|
DeploymentJson = deploymentJson,
|
|
SourceJson = "{\"source\":\"DemoData\",\"composition\":\"Test.Merge.ps1\"}",
|
|
ResolvedJson = deploymentJson,
|
|
SourceSnapshotJson = sourceSnapshotJson,
|
|
InputHash = TemplateVersionModel.ComputeSha256(sourceSnapshotJson),
|
|
OutputHash = TemplateVersionModel.ComputeSha256(deploymentJson),
|
|
IsStale = false
|
|
})
|
|
];
|
|
}
|
|
|
|
private static object[] CredentialSecrets() =>
|
|
[
|
|
CredentialSecret(CredentialSharePointSetupId, "Windows/SharePoint/SetupAccount", "CONTOSO\\svc_sp_setup"),
|
|
CredentialSecret(CredentialSharePointFarmId, "Windows/SharePoint/FarmAccount", "CONTOSO\\svc_sp_farm"),
|
|
CredentialSecret(CredentialSharePointFarmPassphraseId, "Windows/SharePoint/FarmPassphrase", null, "Secret"),
|
|
CredentialSecret(CredentialSharePointDefaultServiceId, "Windows/SharePoint/DefaultServiceAccount", "CONTOSO\\svc_sp_service"),
|
|
CredentialSecret(CredentialSharePointSearchId, "Windows/SharePoint/SearchAccount", "CONTOSO\\svc_sp_search")
|
|
];
|
|
|
|
private static object[] ApiClients() =>
|
|
[
|
|
Base(new ApiClientModel
|
|
{
|
|
Id = ApiClientDemoWorkerId,
|
|
ClientId = "ssp-demo-worker",
|
|
Name = "Demo Worker Client",
|
|
SecretHash = ApiClientSecretHasher.HashSecretForDemoData("DemoOnly-DoNotUseInProduction!", "ssp-demo-worker"),
|
|
ScopesJson = "[\"deployment.read\",\"deployment.write\",\"queue.process\",\"template.read\",\"credential.resolve\",\"token.manage\",\"token.admin\"]",
|
|
IsEnabled = true
|
|
})
|
|
];
|
|
|
|
private static TemplateVersionModel TemplateVersion(Guid id, Guid templateId, string jsonData)
|
|
{
|
|
return Base(new TemplateVersionModel
|
|
{
|
|
Id = id,
|
|
TemplateId = templateId,
|
|
Version = "1.0.0",
|
|
JsonData = jsonData,
|
|
JsonHash = TemplateVersionModel.ComputeSha256(jsonData),
|
|
SchemaVersion = "1.0",
|
|
IsPublished = true,
|
|
PublishedAt = Timestamp,
|
|
PublishedBy = Owner
|
|
});
|
|
}
|
|
|
|
private static TemplateRevisionModel TemplateRevision(Guid id, Guid templateVersionId, string jsonData)
|
|
{
|
|
return Base(new TemplateRevisionModel
|
|
{
|
|
Id = id,
|
|
TemplateVersionId = templateVersionId,
|
|
RevisionNumber = 1,
|
|
JsonData = jsonData,
|
|
JsonHash = TemplateVersionModel.ComputeSha256(jsonData),
|
|
SchemaVersion = "1.0",
|
|
IsCurrent = true,
|
|
IsPublished = true,
|
|
PublishedAt = Timestamp,
|
|
PublishedBy = Owner
|
|
});
|
|
}
|
|
|
|
private static CredentialSecretModel CredentialSecret(Guid id, string name, string? userName, string secretType = "Credential")
|
|
{
|
|
return Base(new CredentialSecretModel
|
|
{
|
|
Id = id,
|
|
Name = name,
|
|
UserName = userName,
|
|
SecretValue = "DemoOnly-DoNotUseInProduction!",
|
|
SecretType = secretType,
|
|
MetadataJson = "{\"environment\":\"Demo\",\"plaintext\":true}",
|
|
IsEnabled = true
|
|
});
|
|
}
|
|
|
|
private static IEnumerable<(Guid RevisionId, string JsonData)> TemplateRevisionJsonDocuments()
|
|
{
|
|
yield return (TemplateActiveDirectoryRevisionId, ActiveDirectoryTemplateJson);
|
|
yield return (TemplateSqlServerRevisionId, SqlServerTemplateJson);
|
|
yield return (TemplateSharePointRevisionId, SharePointTemplateJson);
|
|
yield return (TemplateTeamsRevisionId, TeamsTemplateJson);
|
|
yield return (TemplateBgwEnvironmentTestRevisionId, BgwEnvironmentTestTemplateJson);
|
|
yield return (TemplateBgwDomainContosoRevisionId, BgwDomainContosoTemplateJson);
|
|
yield return (TemplateBgwSharePointContosoRevisionId, BgwSharePointContosoTemplateJson);
|
|
yield return (TemplateBgwStageInstallRevisionId, BgwStageInstallTemplateJson);
|
|
}
|
|
|
|
private static IEnumerable<ConfigurationDefinitionModel> ExtractConfigurationDefinitions(Guid revisionId, string jsonData)
|
|
{
|
|
using var document = JsonDocument.Parse(jsonData);
|
|
var root = document.RootElement;
|
|
|
|
foreach (var definition in ExtractConfigurationDefinitions(revisionId, root, "parameters", ConfigurationDefinitionKinds.Parameter))
|
|
yield return definition;
|
|
|
|
foreach (var definition in ExtractConfigurationDefinitions(revisionId, root, "variables", ConfigurationDefinitionKinds.Variable))
|
|
yield return definition;
|
|
}
|
|
|
|
private static IEnumerable<ConfigurationDefinitionModel> ExtractConfigurationDefinitions(Guid revisionId, JsonElement root, string propertyName, string kind)
|
|
{
|
|
if (!root.TryGetProperty(propertyName, out var definitions) || definitions.ValueKind != JsonValueKind.Object)
|
|
yield break;
|
|
|
|
foreach (var property in definitions.EnumerateObject())
|
|
{
|
|
var propertiesJson = kind == ConfigurationDefinitionKinds.Variable
|
|
? $$"""{"Expression":{{property.Value.GetRawText()}}}"""
|
|
: property.Value.GetRawText();
|
|
yield return new ConfigurationDefinitionModel
|
|
{
|
|
Id = ConfigurationDefinitionId(revisionId, kind, property.Name),
|
|
TemplateRevisionId = revisionId,
|
|
Kind = kind,
|
|
Name = property.Name,
|
|
PropertiesJson = propertiesJson,
|
|
DefinitionHash = TemplateVersionModel.ComputeSha256(propertiesJson)
|
|
};
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<ConfigurationValueModel> ExtractConfigurationValues(Guid revisionId, string jsonData)
|
|
{
|
|
using var document = JsonDocument.Parse(jsonData);
|
|
var root = document.RootElement;
|
|
|
|
foreach (var value in ExtractParameterValues(revisionId, root))
|
|
yield return value;
|
|
|
|
foreach (var value in ExtractVariableValues(revisionId, root))
|
|
yield return value;
|
|
}
|
|
|
|
private static IEnumerable<ConfigurationValueModel> ExtractParameterValues(Guid revisionId, JsonElement root)
|
|
{
|
|
if (!root.TryGetProperty("parameters", out var parameters) || parameters.ValueKind != JsonValueKind.Object)
|
|
yield break;
|
|
|
|
var sortOrder = 0;
|
|
foreach (var parameter in parameters.EnumerateObject())
|
|
{
|
|
sortOrder += 10;
|
|
|
|
var valueSourceType = ConfigurationValueSourceTypes.Static;
|
|
var valueJson = "{}";
|
|
|
|
if (parameter.Value.ValueKind == JsonValueKind.Object && parameter.Value.TryGetProperty("Value", out var explicitValue))
|
|
{
|
|
valueJson = $$"""{"value":{{explicitValue.GetRawText()}}}""";
|
|
}
|
|
else if (parameter.Value.ValueKind == JsonValueKind.Object && parameter.Value.TryGetProperty("DefaultValue", out var defaultValue))
|
|
{
|
|
valueJson = $$"""{"value":{{defaultValue.GetRawText()}}}""";
|
|
}
|
|
|
|
if (parameter.Value.ValueKind == JsonValueKind.Object
|
|
&& parameter.Value.TryGetProperty("Sensitive", out var sensitive)
|
|
&& sensitive.ValueKind == JsonValueKind.True)
|
|
{
|
|
valueSourceType = ConfigurationValueSourceTypes.SecretReference;
|
|
}
|
|
|
|
yield return ConfigurationValue(
|
|
revisionId,
|
|
ConfigurationDefinitionKinds.Parameter,
|
|
parameter.Name,
|
|
valueSourceType,
|
|
valueJson,
|
|
sortOrder);
|
|
}
|
|
}
|
|
|
|
private static IEnumerable<ConfigurationValueModel> ExtractVariableValues(Guid revisionId, JsonElement root)
|
|
{
|
|
if (!root.TryGetProperty("variables", out var variables) || variables.ValueKind != JsonValueKind.Object)
|
|
yield break;
|
|
|
|
var sortOrder = 0;
|
|
foreach (var variable in variables.EnumerateObject())
|
|
{
|
|
sortOrder += 10;
|
|
var valueJson = $$"""{"expression":{{variable.Value.GetRawText()}}}""";
|
|
|
|
yield return ConfigurationValue(
|
|
revisionId,
|
|
ConfigurationDefinitionKinds.Variable,
|
|
variable.Name,
|
|
ConfigurationValueSourceTypes.Expression,
|
|
valueJson,
|
|
sortOrder);
|
|
}
|
|
}
|
|
|
|
private static ConfigurationValueModel ConfigurationValue(Guid revisionId, string kind, string name, string valueSourceType, string valueJson, int sortOrder)
|
|
{
|
|
return new ConfigurationValueModel
|
|
{
|
|
Id = ConfigurationValueId(revisionId, kind, name),
|
|
ConfigurationDefinitionId = ConfigurationDefinitionId(revisionId, kind, name),
|
|
ScopeType = ConfigurationValueScopeTypes.TemplateRevision,
|
|
ScopeId = revisionId,
|
|
ValueSourceType = valueSourceType,
|
|
ValueJson = valueJson,
|
|
ValueHash = TemplateVersionModel.ComputeSha256(valueJson),
|
|
SortOrder = sortOrder
|
|
};
|
|
}
|
|
|
|
private static Guid ConfigurationDefinitionId(Guid revisionId, string kind, string name)
|
|
{
|
|
return DeterministicGuid($"ConfigurationDefinition:{revisionId:N}:{kind}:{name}");
|
|
}
|
|
|
|
private static Guid ConfigurationValueId(Guid revisionId, string kind, string name)
|
|
{
|
|
return DeterministicGuid($"ConfigurationValue:{revisionId:N}:{kind}:{name}");
|
|
}
|
|
|
|
private static Guid DeterministicGuid(string value)
|
|
{
|
|
var hash = MD5.HashData(Encoding.UTF8.GetBytes(value));
|
|
return new Guid(hash);
|
|
}
|
|
|
|
private static string BgwMergeSourceSnapshotJson()
|
|
{
|
|
return $$"""
|
|
{
|
|
"templateRevisions": [
|
|
{
|
|
"id": "{{TemplateBgwEnvironmentTestRevisionId}}",
|
|
"templateVersionId": "{{TemplateBgwEnvironmentTestVersionId}}",
|
|
"role": "Environment",
|
|
"alias": "Environment-Test",
|
|
"hash": "{{TemplateVersionModel.ComputeSha256(BgwEnvironmentTestTemplateJson)}}"
|
|
},
|
|
{
|
|
"id": "{{TemplateBgwDomainContosoRevisionId}}",
|
|
"templateVersionId": "{{TemplateBgwDomainContosoVersionId}}",
|
|
"role": "Domain",
|
|
"alias": "Domain-Contoso",
|
|
"hash": "{{TemplateVersionModel.ComputeSha256(BgwDomainContosoTemplateJson)}}"
|
|
},
|
|
{
|
|
"id": "{{TemplateBgwSharePointContosoRevisionId}}",
|
|
"templateVersionId": "{{TemplateBgwSharePointContosoVersionId}}",
|
|
"role": "Service",
|
|
"alias": "Service-SharePoint-Contoso",
|
|
"hash": "{{TemplateVersionModel.ComputeSha256(BgwSharePointContosoTemplateJson)}}"
|
|
},
|
|
{
|
|
"id": "{{TemplateBgwStageInstallRevisionId}}",
|
|
"templateVersionId": "{{TemplateBgwStageInstallVersionId}}",
|
|
"role": "Stage",
|
|
"alias": "Stage-Install",
|
|
"hash": "{{TemplateVersionModel.ComputeSha256(BgwStageInstallTemplateJson)}}"
|
|
}
|
|
],
|
|
"targets": [
|
|
{ "id": "{{TargetBgwSp01Id}}", "nodeName": "CLD-SHP-01" },
|
|
{ "id": "{{TargetBgwSp02Id}}", "nodeName": "CLD-SHP-02" },
|
|
{ "id": "{{TargetBgwSp03Id}}", "nodeName": "CLD-SHP-03" }
|
|
]
|
|
}
|
|
""";
|
|
}
|
|
|
|
private static T Base<T>(T model)
|
|
where T : BaseModel
|
|
{
|
|
model.Created = Timestamp;
|
|
model.Modified = Timestamp;
|
|
model.CreatedBy = Owner;
|
|
model.ModifiedBy = Owner;
|
|
return model;
|
|
}
|
|
|
|
private static T Junction<T>(T model)
|
|
where T : BaseJunctionModel
|
|
{
|
|
model.Created = Timestamp;
|
|
model.Modified = Timestamp;
|
|
model.CreatedBy = Owner;
|
|
model.ModifiedBy = Owner;
|
|
return model;
|
|
}
|
|
|
|
private const string ActiveDirectoryTemplateJson = """
|
|
{
|
|
"schemaVersion": "1.0",
|
|
"templateType": "Service",
|
|
"parameters": {
|
|
"DomainName": { "type": "string", "defaultValue": "corp.contoso.com" },
|
|
"NetBIOSName": { "type": "string", "defaultValue": "CONTOSO" }
|
|
},
|
|
"variables": {
|
|
"DefaultSiteName": "[concat(parameters('DomainName'), '-DefaultSite')]"
|
|
},
|
|
"resources": {
|
|
"AllNodes": [
|
|
{ "NodeName": "*", "PSDscAllowPlainTextPassword": true }
|
|
],
|
|
"NonNodeData": {
|
|
"Services": {
|
|
"ActiveDirectory": {
|
|
"DomainName": "[parameters('DomainName')]",
|
|
"NetBIOSName": "[parameters('NetBIOSName')]"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
|
|
private const string SqlServerTemplateJson = """
|
|
{
|
|
"schemaVersion": "1.0",
|
|
"templateType": "Service",
|
|
"parameters": {
|
|
"InstanceName": { "type": "string", "defaultValue": "MSSQLSERVER" },
|
|
"DatabasePrefix": { "type": "string", "defaultValue": "Contoso" }
|
|
},
|
|
"variables": {
|
|
"ConfigDatabase": "[concat(parameters('DatabasePrefix'), '_Config')]"
|
|
},
|
|
"resources": {
|
|
"NonNodeData": {
|
|
"Services": {
|
|
"SqlServer": {
|
|
"InstanceName": "[parameters('InstanceName')]",
|
|
"ConfigDatabase": "[variables('ConfigDatabase')]"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
|
|
private const string SharePointTemplateJson = """
|
|
{
|
|
"schemaVersion": "1.0",
|
|
"templateType": "Service",
|
|
"parameters": {
|
|
"DatabasePrefix": { "type": "string", "defaultValue": "SharePoint_Contoso_Test" },
|
|
"FarmAccount": { "type": "credential", "metadata": { "description": "Farm account resolved by the credential provider." } }
|
|
},
|
|
"variables": {
|
|
"ConfigDbName": "[concat(parameters('DatabasePrefix'), '_Farm_Config')]",
|
|
"AdminContentDbName": "[concat(parameters('DatabasePrefix'), '_AdminContent')]"
|
|
},
|
|
"resources": {
|
|
"NonNodeData": {
|
|
"Services": {
|
|
"SharePoint": {
|
|
"Farm": {
|
|
"ConfigDatabase": "[variables('ConfigDbName')]",
|
|
"AdminContentDatabase": "[variables('AdminContentDbName')]",
|
|
"ManagedAccounts": {
|
|
"FarmAccount": "[parameters('FarmAccount')]"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
|
|
private const string TeamsTemplateJson = """
|
|
{
|
|
"schemaVersion": "1.0",
|
|
"templateType": "Service",
|
|
"parameters": {
|
|
"CallingPolicyName": { "type": "string", "defaultValue": "Contoso-Standard-Calling" },
|
|
"MeetingPolicyName": { "type": "string", "defaultValue": "Contoso-Standard-Meetings" }
|
|
},
|
|
"variables": {},
|
|
"resources": {
|
|
"NonNodeData": {
|
|
"Services": {
|
|
"Teams": {
|
|
"CallingPolicy": "[parameters('CallingPolicyName')]",
|
|
"MeetingPolicy": "[parameters('MeetingPolicyName')]"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
}
|
|
}
|
|
|