Example #1
0
 public ResourceType GetType(ResourceTypeReference reference)
 => new ResourceType(reference, new NamedObjectType(reference.FormatName(), TypeSymbolValidationFlags.Default, LanguageConstants.CreateResourceProperties(reference), null), TypeSymbolValidationFlags.Default);
        public ResourceType GetType(ResourceTypeReference typeReference)
        {
            if (loadedTypeCache.TryGetValue(typeReference, out var resourceType))
            {
                return(resourceType);
            }

            if (availableResourceTypes.TryGetValue(typeReference, out var typeLocation))
            {
                // It's important to cache this result because LoadResourceType is an expensive operation, and
                // duplicating types means the resourceTypeFactor won't be able to use its cache.
                var serializedResourceType = typeLoader.LoadResourceType(typeLocation);
                resourceType = resourceTypeFactory.GetResourceType(serializedResourceType);
            }
            else
            {
                resourceType = new ResourceType(typeReference, new NamedObjectType(typeReference.FormatName(), TypeSymbolValidationFlags.Default, LanguageConstants.CreateResourceProperties(typeReference), null), TypeSymbolValidationFlags.Default);
            }

            loadedTypeCache[typeReference] = resourceType;
            return(resourceType);
        }
Example #3
0
 public static TypeSymbol?TryGetPrimitiveType(ParameterDeclarationSyntax parameterDeclarationSyntax)
 => LanguageConstants.TryGetDeclarationType(parameterDeclarationSyntax.Type.TypeName);
Example #4
0
        public ResourceType GetType(ResourceTypeReference typeReference)
        {
            var resourceType = TryGetResource(typeReference);

            if (resourceType != null)
            {
                return(resourceType);
            }

            // TODO move default definition into types assembly
            return(new ResourceType(typeReference, new NamedObjectType(typeReference.FormatName(), LanguageConstants.CreateResourceProperties(typeReference), null)));
        }
Example #5
0
        private static ResourceType FallbackPropertyTestsType()
        {
            var resourceType = ResourceTypeReference.Parse("Test.Rp/fallbackProperties@2020-01-01");

            var propertiesType = new ObjectType("Properties", TypeSymbolValidationFlags.WarnOnTypeMismatch, new[] {
                new TypeProperty("required", LanguageConstants.String, TypePropertyFlags.Required, "This is a property which is required."),
            }, null);

            return(new ResourceType(resourceType, ResourceScope.ResourceGroup, new ObjectType(resourceType.FormatName(), TypeSymbolValidationFlags.Default,
                                                                                              GetCommonResourceProperties(resourceType).Concat(new[] {
                new TypeProperty("properties", propertiesType, TypePropertyFlags.Required, "properties property"),
            }).Concat(
                                                                                                  LanguageConstants.KnownTopLevelResourceProperties().Where(p => !string.Equals(p.Name, "properties", LanguageConstants.IdentifierComparison))
                                                                                                  .Select(p => new TypeProperty(p.Name, p.TypeReference, TypePropertyFlags.None, "Property that does something important"))
                                                                                                  ), null)));
        }
Example #6
0
 public ResourceType GetType(ResourceTypeReference reference)
 => new ResourceType(reference, LanguageConstants.CreateResourceProperties(reference));
Example #7
0
        private static (ResourceTypeReference, Func <ResourceType>) Get_Microsoft_Resources_deploymentScripts_2020_10_01()
        {
            // hand crafted from https://github.com/Azure/azure-rest-api-specs/blob/405df4e/specification/resources/resource-manager/Microsoft.Resources/preview/2019-10-01-preview/deploymentScripts.json
            var reference = ResourceTypeReference.Parse("Microsoft.Resources/deploymentScripts@2019-10-01-preview");

            var userAssignedIdentity = new NamedObjectType(
                "UserAssignedIdentity",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("clientId", LanguageConstants.String),
                new TypeProperty("principalId", LanguageConstants.String),
            },
                null);

            var identity = new NamedObjectType(
                "ManagedServiceIdentity",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("type", CreateEnumType("UserAssigned"), TypePropertyFlags.None),
                new TypeProperty("userAssignedIdentities", new NamedObjectType("UserAssignedIdentities", TypeSymbolValidationFlags.WarnOnTypeMismatch, Enumerable.Empty <TypeProperty>(), userAssignedIdentity), TypePropertyFlags.None),
            },
                null);

            var containerConfiguration = new NamedObjectType(
                "ContainerConfiguration",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("containerGroupName", LanguageConstants.String, TypePropertyFlags.None),
            },
                null);

            var environmentVariable = new NamedObjectType(
                "EnvironmentVariable",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("name", LanguageConstants.String, TypePropertyFlags.Required),
                new TypeProperty("secureValue", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("value", LanguageConstants.String, TypePropertyFlags.None),
            },
                null);

            var storageAccountConfiguration = new NamedObjectType(
                "StorageAccountConfiguration",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("storageAccountKey", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("storageAccountName", LanguageConstants.String, TypePropertyFlags.None),
            },
                null);

            var scriptStatus = new NamedObjectType(
                "ScriptStatus",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                new [] {
                new TypeProperty("containerInstanceId", LanguageConstants.String, TypePropertyFlags.ReadOnly),
                new TypeProperty("storageAccountId", LanguageConstants.String, TypePropertyFlags.ReadOnly),
                new TypeProperty("startTime", LanguageConstants.String, TypePropertyFlags.ReadOnly),
                new TypeProperty("endTime", LanguageConstants.String, TypePropertyFlags.ReadOnly),
                new TypeProperty("expirationTime", LanguageConstants.String, TypePropertyFlags.ReadOnly),
                new TypeProperty("error", LanguageConstants.Any, TypePropertyFlags.ReadOnly),
            },
                null);

            var baseResource = LanguageConstants.GetCommonResourceProperties(reference).Concat(
                new TypeProperty("location", LanguageConstants.String, TypePropertyFlags.Required),
                new TypeProperty("tags", LanguageConstants.Tags, TypePropertyFlags.None),
                new TypeProperty("identity", identity, TypePropertyFlags.Required));

            var deploymentScriptPropertiesBase = new [] {
                new TypeProperty("containerSettings", containerConfiguration, TypePropertyFlags.None),
                new TypeProperty("storageAccountSettings", storageAccountConfiguration, TypePropertyFlags.None),
                new TypeProperty("cleanupPreference", UnionType.Create(new StringLiteralType("Always"), new StringLiteralType("OnSuccess"), new StringLiteralType("OnExpiration")), TypePropertyFlags.None),
                new TypeProperty("provisioningState", CreateEnumType("Creating", "ProvisioningResources", "Running", "Succeeded", "Failed", "Canceled"), TypePropertyFlags.ReadOnly),
                new TypeProperty("status", scriptStatus, TypePropertyFlags.ReadOnly),
                new TypeProperty("outputs", LanguageConstants.Any, TypePropertyFlags.ReadOnly),
            };

            var scriptConfigurationBase = new [] {
                new TypeProperty("primaryScriptUri", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("supportingScriptUris", new TypedArrayType(LanguageConstants.String, TypeSymbolValidationFlags.WarnOnTypeMismatch), TypePropertyFlags.None),
                new TypeProperty("scriptContent", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("arguments", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("environmentVariables", new TypedArrayType(environmentVariable, TypeSymbolValidationFlags.WarnOnTypeMismatch), TypePropertyFlags.None),
                new TypeProperty("forceUpdateTag", LanguageConstants.String, TypePropertyFlags.None),
                new TypeProperty("retentionInterval", LanguageConstants.String, TypePropertyFlags.Required),
                new TypeProperty("timeout", LanguageConstants.String, TypePropertyFlags.None),
            };

            var powerShellResourceProperties = new NamedObjectType(
                "AzurePowerShellScriptProperties",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                deploymentScriptPropertiesBase.Concat(scriptConfigurationBase).Concat(
                    new TypeProperty("azPowerShellVersion", LanguageConstants.String, TypePropertyFlags.Required)
                    ),
                null);

            var powerShellResource = new NamedObjectType(
                "AzurePowerShellScript",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                baseResource.Concat(
                    new TypeProperty("kind", new StringLiteralType("AzurePowerShell"), TypePropertyFlags.Required),
                    new TypeProperty("properties", powerShellResourceProperties, TypePropertyFlags.Required)),
                null);

            var azCliResourceProperties = new NamedObjectType(
                "AzureCliScriptProperties",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                deploymentScriptPropertiesBase.Concat(scriptConfigurationBase).Concat(
                    new TypeProperty("azCliVersion", LanguageConstants.String, TypePropertyFlags.Required)
                    ),
                null);

            var azCliResource = new NamedObjectType(
                "AzureCliScript",
                TypeSymbolValidationFlags.WarnOnTypeMismatch,
                baseResource.Concat(
                    new TypeProperty("kind", new StringLiteralType("AzureCLI"), TypePropertyFlags.Required),
                    new TypeProperty("properties", azCliResourceProperties, TypePropertyFlags.Required)),
                null);

            return(reference, () => new ResourceType(
                       reference,
                       new DiscriminatedObjectType(
                           reference.FormatName(),
                           TypeSymbolValidationFlags.WarnOnTypeMismatch,
                           "kind",
                           new [] {
                powerShellResource,
                azCliResource,
            }),
                       TypeSymbolValidationFlags.WarnOnTypeMismatch));
        }
Example #8
0
        public void ParameterModifierShouldRejectAdditionalProperties()
        {
            var obj = TestSyntaxFactory.CreateObject(new []
            {
                TestSyntaxFactory.CreateProperty("extra", TestSyntaxFactory.CreateString("foo")),
                TestSyntaxFactory.CreateProperty("extra2", TestSyntaxFactory.CreateString("foo"))
            });

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.String))
            .Select(e => e.Message)
            .Should()
            .Equal(
                "The property 'extra' is not allowed on objects of type ParameterModifier_string.",
                "The property 'extra2' is not allowed on objects of type ParameterModifier_string.");
        }
Example #9
0
 public TypeSymbol?TryGetPrimitiveType()
 => LanguageConstants.TryGetDeclarationType(this.DeclaringParameter.Type.TypeName);
Example #10
0
 public ResourceType GetType(ResourceTypeReference reference)
 => new ResourceType(reference, new NamedObjectType(reference.FormatName(), LanguageConstants.CreateResourceProperties(reference), null));
        public void CompletelyInvalidArrayParameterModifier_ShouldLogExpectedErrors()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                // not a bool
                TestSyntaxFactory.CreateProperty("secure", TestSyntaxFactory.CreateInt(1)),

                // default value of wrong type
                TestSyntaxFactory.CreateProperty("default", TestSyntaxFactory.CreateBool(true)),

                // not an array
                TestSyntaxFactory.CreateProperty("allowed", TestSyntaxFactory.CreateObject(new ObjectPropertySyntax[0])),

                // not ints
                TestSyntaxFactory.CreateProperty("minValue", TestSyntaxFactory.CreateBool(true)),
                TestSyntaxFactory.CreateProperty("maxValue", TestSyntaxFactory.CreateString("11")),
                TestSyntaxFactory.CreateProperty("minLength", TestSyntaxFactory.CreateObject(new ObjectPropertySyntax[0])),
                TestSyntaxFactory.CreateProperty("maxLength", TestSyntaxFactory.CreateBool(false)),

                // extra property
                TestSyntaxFactory.CreateProperty("extra", TestSyntaxFactory.CreateBool(false)),

                TestSyntaxFactory.CreateProperty("metadata", TestSyntaxFactory.CreateObject(new[]
                {
                    // wrong type of description
                    TestSyntaxFactory.CreateProperty("description", TestSyntaxFactory.CreateInt(155))
                }))
            });

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.Array, LanguageConstants.Array))
            .Select(d => d.Message)
            .Should()
            .BeEquivalentTo(
                "The property 'default' expected a value of type array but the provided value is of type bool.",
                "The property 'maxLength' expected a value of type int but the provided value is of type bool.",
                "The property 'allowed' expected a value of type array[] but the provided value is of type object.",
                "The property 'minLength' expected a value of type int but the provided value is of type object.",
                "The property 'description' expected a value of type string but the provided value is of type int.",
                "The property 'secure' is not allowed on objects of type ParameterModifier<array>.",
                "The property 'minValue' is not allowed on objects of type ParameterModifier<array>.",
                "The property 'maxValue' is not allowed on objects of type ParameterModifier<array>.",
                "The property 'extra' is not allowed on objects of type ParameterModifier<array>.");
        }
        public void Valid_parameter_modifier_should_ensure_default_value_is_assignable_to_allowed_values()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                TestSyntaxFactory.CreateProperty("default", TestSyntaxFactory.CreateString("Three")),

                TestSyntaxFactory.CreateProperty("allowed", TestSyntaxFactory.CreateArray(new []
                {
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateString("One")),
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateString("Two")),
                })),
            });

            var allowedValuesType = UnionType.Create(new StringLiteralType("One"), new StringLiteralType("Two"));

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.String, allowedValuesType))
            .Should().SatisfyRespectively(
                x => x.Message.Should().Be("The property 'default' expected a value of type 'One' | 'Two' but the provided value is of type 'Three'."));
        }
        public void ParameterModifierShouldRejectAdditionalProperties()
        {
            var obj = TestSyntaxFactory.CreateObject(new []
            {
                TestSyntaxFactory.CreateProperty("extra", TestSyntaxFactory.CreateString("foo")),
                TestSyntaxFactory.CreateProperty("extra2", TestSyntaxFactory.CreateString("foo"))
            });

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.String, LanguageConstants.String))
            .Select(e => e.Message)
            .Should()
            .Equal(
                "The property 'extra' is not allowed on objects of type ParameterModifier<string>. Permissible properties include 'allowed', 'default', 'maxLength', 'metadata', 'minLength', 'secure'.",
                "The property 'extra2' is not allowed on objects of type ParameterModifier<string>. Permissible properties include 'allowed', 'default', 'maxLength', 'metadata', 'minLength', 'secure'.");
        }
Example #14
0
        public ResourceType GetType(ResourceTypeReference reference, ResourceTypeGenerationFlags flags)
        {
            var bodyType     = new ObjectType(reference.FormatName(), TypeSymbolValidationFlags.Default, LanguageConstants.CreateResourceProperties(reference), null);
            var resourceType = new ResourceType(reference, ResourceScope.Tenant | ResourceScope.ManagementGroup | ResourceScope.Subscription | ResourceScope.ResourceGroup | ResourceScope.Resource, bodyType);

            return(AzResourceTypeProvider.SetBicepResourceProperties(resourceType, flags));
        }
Example #15
0
        public override IEnumerable <ErrorDiagnostic> GetDiagnostics()
        {
            var diagnostics = this.ValidateIdentifierAccess();

            switch (this.Modifier)
            {
            case ParameterDefaultValueSyntax defaultValueSyntax:
                diagnostics = diagnostics.Concat(ValidateDefaultValue(defaultValueSyntax));
                break;

            case ObjectSyntax modifierSyntax when this.Type.TypeKind != TypeKind.Error:
                diagnostics = diagnostics.Concat(TypeValidator.GetExpressionAssignmentDiagnostics(this.Context.TypeManager, modifierSyntax, LanguageConstants.CreateParameterModifierType(this.Type)));
                break;
            }

            return(diagnostics);
        }
Example #16
0
        public void EmptyModifierIsValid()
        {
            var obj = TestSyntaxFactory.CreateObject(new ObjectPropertySyntax[0]);

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.Int)).Should().BeEmpty();
        }
Example #17
0
        private ResourceType GenerateResourceType(ResourceTypeReference typeReference, bool isExistingResource)
        {
            if (availableResourceTypes.TryGetValue(typeReference, out var typeLocation))
            {
                var serializedResourceType = typeLoader.LoadResourceType(typeLocation);
                var resourceType           = resourceTypeFactory.GetResourceType(serializedResourceType);

                return(SetBicepResourceProperties(resourceType, isExistingResource));
            }
            else
            {
                var resourceBodyType = new NamedObjectType(typeReference.FormatName(), TypeSymbolValidationFlags.Default, LanguageConstants.CreateResourceProperties(typeReference), null);
                var resourceType     = new ResourceType(typeReference, ResourceScope.Tenant | ResourceScope.ManagementGroup | ResourceScope.Subscription | ResourceScope.ResourceGroup | ResourceScope.Resource, resourceBodyType);

                return(SetBicepResourceProperties(resourceType, isExistingResource));
            }
        }
Example #18
0
        public void ValidStringParameterModifierShouldProduceNoDiagnostics()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                TestSyntaxFactory.CreateProperty("secure", TestSyntaxFactory.CreateBool(false)),
                TestSyntaxFactory.CreateProperty("default", TestSyntaxFactory.CreateString("foo")),

                TestSyntaxFactory.CreateProperty("allowed", TestSyntaxFactory.CreateArray(new []
                {
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateString("One"))
                })),

                TestSyntaxFactory.CreateProperty("minLength", TestSyntaxFactory.CreateInt(33)),
                TestSyntaxFactory.CreateProperty("maxLength", TestSyntaxFactory.CreateInt(25)),

                TestSyntaxFactory.CreateProperty("metadata", TestSyntaxFactory.CreateObject(new[]
                {
                    TestSyntaxFactory.CreateProperty("description", TestSyntaxFactory.CreateString("my description")),
                    TestSyntaxFactory.CreateProperty("extra1", TestSyntaxFactory.CreateString("extra")),
                    TestSyntaxFactory.CreateProperty("extra2", TestSyntaxFactory.CreateBool(true)),
                    TestSyntaxFactory.CreateProperty("extra3", TestSyntaxFactory.CreateInt(100))
                }))
            });

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.String)).Should().BeEmpty();
        }
        public void CompletelyInvalidBoolParameterModifier_ShouldLogExpectedErrors()
        {
            var obj = TestSyntaxFactory.CreateObject(new[]
            {
                // not a bool and not allowed
                TestSyntaxFactory.CreateProperty("secure", TestSyntaxFactory.CreateInt(1)),

                // default value of wrong type
                TestSyntaxFactory.CreateProperty("default", TestSyntaxFactory.CreateInt(1231)),

                // not an array
                TestSyntaxFactory.CreateProperty("allowed", TestSyntaxFactory.CreateArray(new []
                {
                    TestSyntaxFactory.CreateArrayItem(TestSyntaxFactory.CreateInt(22))
                })),

                // not allowed
                TestSyntaxFactory.CreateProperty("minValue", TestSyntaxFactory.CreateBool(true)),
                TestSyntaxFactory.CreateProperty("maxValue", TestSyntaxFactory.CreateString("11")),
                TestSyntaxFactory.CreateProperty("minLength", TestSyntaxFactory.CreateObject(new ObjectPropertySyntax[0])),
                TestSyntaxFactory.CreateProperty("maxLength", TestSyntaxFactory.CreateBool(false)),

                // extra property
                TestSyntaxFactory.CreateProperty("extra", TestSyntaxFactory.CreateBool(false)),

                TestSyntaxFactory.CreateProperty("metadata", TestSyntaxFactory.CreateObject(new[]
                {
                    // wrong type of description
                    TestSyntaxFactory.CreateProperty("description", TestSyntaxFactory.CreateInt(155))
                }))
            });

            TypeValidator.GetExpressionAssignmentDiagnostics(CreateTypeManager(), obj, LanguageConstants.CreateParameterModifierType(LanguageConstants.Bool))
            .Select(d => d.Message)
            .Should().BeEquivalentTo(
                "The property 'default' expected a value of type 'bool' but the provided value is of type 'int'.",
                "The enclosing array expected an item of type 'bool', but the provided item was of type 'int'.",
                "The property 'description' expected a value of type 'string' but the provided value is of type 'int'.",
                "The property 'secure' is not allowed on objects of type 'ParameterModifier_bool'.",
                "The property 'minValue' is not allowed on objects of type 'ParameterModifier_bool'.",
                "The property 'maxValue' is not allowed on objects of type 'ParameterModifier_bool'.",
                "The property 'minLength' is not allowed on objects of type 'ParameterModifier_bool'.",
                "The property 'maxLength' is not allowed on objects of type 'ParameterModifier_bool'.",
                "The property 'extra' is not allowed on objects of type 'ParameterModifier_bool'.");
        }