diff --git a/package.json b/package.json index 1f2bd944..06459f5a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "vscode-jsonrpc": "^3.6.2", "winston": "^3.2.1", "yargs": "^6.6.0", - "yasway": "^1.7.1", + "yasway": "Azure/sway#readonly", "yuml2svg": "^4.2.1", "z-schema": "^4.0.2" }, @@ -47,7 +47,7 @@ "@types/js-yaml": "^3.12.1", "@types/json-pointer": "^1.0.30", "@types/jsonpath": "^0.2.0", - "@types/lodash": "^4.14.123", + "@types/lodash": "4.14.123", "@types/md5-file": "^4.0.0", "@types/node": "^10.12.18", "@types/request": "^2.48.1", @@ -62,7 +62,7 @@ "tslint": "^5.16.0", "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.0.1", - "typescript": "^3.4.5" + "typescript": "~3.4.5" }, "homepage": "https://github.com/azure/oav", "repository": { diff --git a/test/modelValidation/swaggers/specification/validateReadOnly/cdn.json b/test/modelValidation/swaggers/specification/validateReadOnly/cdn.json new file mode 100644 index 00000000..53233b25 --- /dev/null +++ b/test/modelValidation/swaggers/specification/validateReadOnly/cdn.json @@ -0,0 +1,1128 @@ +{ + "swagger": "2.0", + "info": { + "version": "2017-04-02", + "title": "CdnManagementClient", + "description": "Use these APIs to manage Azure CDN resources through the Azure Resource Manager. You must make sure that requests made to these resources are secure." + }, + "host": "management.azure.com", + "schemes": ["https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "security": [ + { + "azure_auth": ["user_impersonation"] + } + ], + "securityDefinitions": { + "azure_auth": { + "type": "oauth2", + "authorizationUrl": "https://login.microsoftonline.com/common/oauth2/authorize", + "flow": "implicit", + "description": "Azure Active Directory OAuth2 Flow.", + "scopes": { + "user_impersonation": "impersonate your user account" + } + } + }, + "paths": { + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cdn/profiles/{profileName}": { + "put": { + "tags": ["Profiles"], + "description": "Creates a new CDN profile with a profile name under the specified subscription and resource group.", + "operationId": "Profiles_Create", + "x-ms-examples": { + "Profiles_Create": { + "$ref": "./examples/Profiles_Create.json" + } + }, + "parameters": [ + { + "$ref": "#/parameters/resourceGroupNameParameter" + }, + { + "name": "profileName", + "in": "path", + "description": "Name of the CDN profile which is unique within the resource group.", + "required": true, + "type": "string" + }, + { + "description": "Profile properties needed to create a new profile.", + "in": "body", + "name": "profile", + "required": true, + "schema": { + "$ref": "#/definitions/Profile" + } + }, + { + "$ref": "#/parameters/subscriptionIdParameter" + }, + { + "$ref": "#/parameters/apiVersionParameter" + } + ], + "responses": { + "200": { + "description": "OK. The request has succeeded.", + "schema": { + "$ref": "#/definitions/Profile" + } + }, + "201": { + "description": "Created. The request has been fulfilled and a new profile has been created.", + "schema": { + "$ref": "#/definitions/Profile" + } + }, + "202": { + "description": "Accepted. The request has been accepted for processing and the operation will complete asynchronously.", + "schema": { + "$ref": "#/definitions/Profile" + } + }, + "default": { + "description": "CDN error response describing why the operation failed.", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + }, + "x-ms-long-running-operation": true + }, + "patch": { + "tags": ["Profiles"], + "description": "Updates a new CDN profile with a profile name under the specified subscription and resource group.", + "operationId": "Profiles_Update", + "x-ms-examples": { + "Profiles_Create": { + "$ref": "./examples/Profiles_Update.json" + } + }, + "parameters": [ + { + "$ref": "#/parameters/resourceGroupNameParameter" + }, + { + "name": "profileName", + "in": "path", + "description": "Name of the CDN profile which is unique within the resource group.", + "required": true, + "type": "string" + }, + { + "description": "Profile properties needed to update a new profile.", + "in": "body", + "name": "profile", + "required": true, + "schema": { + "$ref": "#/definitions/Profile" + } + }, + { + "$ref": "#/parameters/subscriptionIdParameter" + }, + { + "$ref": "#/parameters/apiVersionParameter" + } + ], + "responses": { + "200": { + "description": "OK. The request has succeeded.", + "schema": { + "$ref": "#/definitions/Profile" + } + }, + "default": { + "description": "CDN error response describing why the operation failed.", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + }, + "x-ms-long-running-operation": true + } + } + }, + "definitions": { + "Profile": { + "description": "CDN profile is a logical grouping of endpoints that share the same settings, such as CDN provider and pricing tier.", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/TrackedResource" + } + ], + "properties": { + "sku": { + "description": "The pricing tier (defines a CDN provider, feature list and rate) of the CDN profile.", + "$ref": "#/definitions/Sku" + }, + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/ProfileProperties" + } + }, + "required": ["sku"] + }, + "ProfileProperties": { + "description": "The JSON object that contains the properties required to create a profile.", + "properties": { + "resourceState": { + "description": "Resource status of the profile.", + "readOnly": true, + "enum": ["Creating", "Active", "Deleting", "Disabled"], + "type": "string", + "x-ms-enum": { + "name": "ProfileResourceState", + "modelAsString": true + } + }, + "provisioningState": { + "readOnly": true, + "description": "Provisioning status of the profile.", + "type": "string" + } + } + }, + "ProfileListResult": { + "description": "Result of the request to list profiles. It contains a list of profile objects and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/Profile" + }, + "description": "List of CDN profiles within a resource group." + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of profile objects if there are any." + } + } + }, + "ProfileUpdateParameters": { + "type": "object", + "description": "Properties required to update a profile.", + "properties": { + "tags": { + "description": "Profile tags", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "x-ms-azure-resource": true + }, + "SsoUri": { + "description": "The URI required to login to the supplemental portal from the Azure portal.", + "type": "object", + "properties": { + "ssoUriValue": { + "description": "The URI used to login to the supplemental portal.", + "readOnly": true, + "type": "string" + } + } + }, + "SupportedOptimizationTypesListResult": { + "description": "The result of the GetSupportedOptimizationTypes API", + "type": "object", + "properties": { + "supportedOptimizationTypes": { + "description": "Supported optimization types for a profile.", + "readOnly": true, + "items": { + "$ref": "#/definitions/OptimizationType" + }, + "type": "array" + } + } + }, + "Endpoint": { + "description": "CDN endpoint is the entity within a CDN profile containing configuration information such as origin, protocol, content caching and delivery behavior. The CDN endpoint uses the URL format .azureedge.net.", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/TrackedResource" + } + ], + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/EndpointProperties" + } + } + }, + "EndpointProperties": { + "description": "The JSON object that contains the properties required to create an endpoint.", + "required": ["origins"], + "allOf": [ + { + "$ref": "#/definitions/EndpointPropertiesUpdateParameters" + } + ], + "properties": { + "hostName": { + "description": "The host name of the endpoint structured as {endpointName}.{DNSZone}, e.g. contoso.azureedge.net", + "type": "string", + "readOnly": true + }, + "origins": { + "description": "The source of the content being delivered via CDN.", + "type": "array", + "items": { + "$ref": "#/definitions/DeepCreatedOrigin" + } + }, + "resourceState": { + "description": "Resource status of the endpoint.", + "readOnly": true, + "enum": ["Creating", "Deleting", "Running", "Starting", "Stopped", "Stopping"], + "type": "string", + "x-ms-enum": { + "name": "EndpointResourceState", + "modelAsString": true + } + }, + "provisioningState": { + "readOnly": true, + "description": "Provisioning status of the endpoint.", + "type": "string" + } + } + }, + "EndpointListResult": { + "description": "Result of the request to list endpoints. It contains a list of endpoint objects and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/Endpoint" + }, + "description": "List of CDN endpoints within a profile" + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of endpoint objects if there is any." + } + } + }, + "EndpointUpdateParameters": { + "type": "object", + "description": "Properties required to create or update an endpoint.", + "properties": { + "tags": { + "description": "Endpoint tags.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/EndpointPropertiesUpdateParameters" + } + }, + "x-ms-azure-resource": true + }, + "EndpointPropertiesUpdateParameters": { + "description": "The JSON object containing endpoint update parameters.", + "properties": { + "originHostHeader": { + "description": "The host header value sent to the origin with each request. If you leave this blank, the request hostname determines this value. Azure CDN origins, such as Web Apps, Blob Storage, and Cloud Services require this host header value to match the origin hostname by default.", + "type": "string" + }, + "originPath": { + "description": "A directory path on the origin that CDN can use to retrieve content from, e.g. contoso.cloudapp.net/originpath.", + "type": "string" + }, + "contentTypesToCompress": { + "description": "List of content types on which compression applies. The value should be a valid MIME type.", + "type": "array", + "items": { + "type": "string" + } + }, + "isCompressionEnabled": { + "description": "Indicates whether content compression is enabled on CDN. Default value is false. If compression is enabled, content will be served as compressed if user requests for a compressed version. Content won't be compressed on CDN when requested content is smaller than 1 byte or larger than 1 MB.", + "type": "boolean" + }, + "isHttpAllowed": { + "description": "Indicates whether HTTP traffic is allowed on the endpoint. Default value is true. At least one protocol (HTTP or HTTPS) must be allowed.", + "type": "boolean" + }, + "isHttpsAllowed": { + "description": "Indicates whether HTTPS traffic is allowed on the endpoint. Default value is true. At least one protocol (HTTP or HTTPS) must be allowed.", + "type": "boolean" + }, + "queryStringCachingBehavior": { + "description": "Defines how CDN caches requests that include query strings. You can ignore any query strings when caching, bypass caching to prevent requests that contain query strings from being cached, or cache every request with a unique URL.", + "$ref": "#/definitions/QueryStringCachingBehavior" + }, + "optimizationType": { + "description": "Specifies what scenario the customer wants this CDN endpoint to optimize for, e.g. Download, Media services. With this information, CDN can apply scenario driven optimization.", + "$ref": "#/definitions/OptimizationType" + }, + "probePath": { + "description": "Path to a file hosted on the origin which helps accelerate delivery of the dynamic content and calculate the most optimal routes for the CDN. This is relative to the origin path.", + "type": "string" + }, + "geoFilters": { + "description": "List of rules defining the user's geo access within a CDN endpoint. Each geo filter defines an access rule to a specified path or content, e.g. block APAC for path /pictures/", + "type": "array", + "items": { + "$ref": "#/definitions/GeoFilter" + } + } + } + }, + "DeepCreatedOrigin": { + "description": "The main origin of CDN content which is added when creating a CDN endpoint.", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "description": "Origin name", + "type": "string" + }, + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/DeepCreatedOriginProperties" + } + }, + "x-ms-azure-resource": true + }, + "DeepCreatedOriginProperties": { + "description": "Properties of the origin created on the CDN endpoint.", + "type": "object", + "required": ["hostName"], + "properties": { + "hostName": { + "description": "The address of the origin. It can be a domain name, IPv4 address, or IPv6 address.", + "type": "string" + }, + "httpPort": { + "description": "The value of the HTTP port. Must be between 1 and 65535", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + }, + "httpsPort": { + "description": "The value of the HTTPS port. Must be between 1 and 65535", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + } + }, + "x-ms-azure-resource": true + }, + "GeoFilter": { + "description": "Rules defining user's geo access within a CDN endpoint.", + "type": "object", + "required": ["relativePath", "action", "countryCodes"], + "properties": { + "relativePath": { + "description": "Relative path applicable to geo filter. (e.g. '/mypictures', '/mypicture/kitty.jpg', and etc.)", + "type": "string" + }, + "action": { + "description": "Action of the geo filter, i.e. allow or block access.", + "enum": ["Block", "Allow"], + "type": "string", + "x-ms-enum": { + "name": "GeoFilterActions", + "modelAsString": false + } + }, + "countryCodes": { + "description": "Two letter country codes defining user country access in a geo filter, e.g. AU, MX, US.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PurgeParameters": { + "type": "object", + "description": "Parameters required for content purge.", + "required": ["contentPaths"], + "properties": { + "contentPaths": { + "description": "The path to the content to be purged. Can describe a file path or a wild card directory.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "LoadParameters": { + "type": "object", + "description": "Parameters required for content load.", + "required": ["contentPaths"], + "properties": { + "contentPaths": { + "description": "The path to the content to be loaded. Path should be a relative file URL of the origin.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "Origin": { + "description": "CDN origin is the source of the content being delivered via CDN. When the edge nodes represented by an endpoint do not have the requested content cached, they attempt to fetch it from one or more of the configured origins.", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/TrackedResource" + } + ], + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/OriginProperties" + } + } + }, + "OriginProperties": { + "description": "The JSON object that contains the properties of the origin.", + "required": ["hostName"], + "properties": { + "hostName": { + "description": "The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.", + "type": "string" + }, + "httpPort": { + "description": "The value of the HTTP port. Must be between 1 and 65535.", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + }, + "httpsPort": { + "description": "The value of the https port. Must be between 1 and 65535.", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + }, + "resourceState": { + "description": "Resource status of the origin.", + "readOnly": true, + "enum": ["Creating", "Active", "Deleting"], + "type": "string", + "x-ms-enum": { + "name": "OriginResourceState", + "modelAsString": true + } + }, + "provisioningState": { + "readOnly": true, + "description": "Provisioning status of the origin.", + "type": "string" + } + } + }, + "OriginUpdateParameters": { + "type": "object", + "description": "Origin properties needed for origin creation or update.", + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/OriginPropertiesParameters" + } + }, + "x-ms-azure-resource": true + }, + "OriginPropertiesParameters": { + "description": "The JSON object that contains the properties of the origin.", + "properties": { + "hostName": { + "description": "The address of the origin. Domain names, IPv4 addresses, and IPv6 addresses are supported.", + "type": "string" + }, + "httpPort": { + "description": "The value of the HTTP port. Must be between 1 and 65535.", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + }, + "httpsPort": { + "description": "The value of the HTTPS port. Must be between 1 and 65535.", + "type": "integer", + "maximum": 65535, + "exclusiveMaximum": false, + "minimum": 1, + "exclusiveMinimum": false + } + } + }, + "OriginListResult": { + "description": "Result of the request to list origins. It contains a list of origin objects and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/Origin" + }, + "description": "List of CDN origins within an endpoint" + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of origin objects if there are any." + } + } + }, + "CustomDomain": { + "description": "Friendly domain name mapping to the endpoint hostname that the customer provides for branding purposes, e.g. www.contoso.com.", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ProxyResource" + } + ], + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/CustomDomainProperties" + } + } + }, + "CustomDomainProperties": { + "description": "The JSON object that contains the properties of the custom domain to create.", + "required": ["hostName"], + "properties": { + "hostName": { + "description": "The host name of the custom domain. Must be a domain name.", + "type": "string" + }, + "resourceState": { + "description": "Resource status of the custom domain.", + "readOnly": true, + "enum": ["Creating", "Active", "Deleting"], + "type": "string", + "x-ms-enum": { + "name": "CustomDomainResourceState", + "modelAsString": true + } + }, + "customHttpsProvisioningState": { + "description": "Provisioning status of Custom Https of the custom domain.", + "readOnly": true, + "enum": ["Enabling", "Enabled", "Disabling", "Disabled", "Failed"], + "type": "string", + "x-ms-enum": { + "name": "CustomHttpsProvisioningState", + "modelAsString": true + } + }, + "customHttpsProvisioningSubstate": { + "description": "Provisioning substate shows the progress of custom HTTPS enabling/disabling process step by step.", + "readOnly": true, + "enum": [ + "SubmittingDomainControlValidationRequest", + "PendingDomainControlValidationREquestApproval", + "DomainControlValidationRequestApproved", + "DomainControlValidationRequestRejected", + "DomainControlValidationRequestTimedOut", + "IssuingCertificate", + "DeployingCertificate", + "CertificateDeployed", + "DeletingCertificate", + "CertificateDeleted" + ], + "type": "string", + "x-ms-enum": { + "name": "CustomHttpsProvisioningSubstate", + "modelAsString": true + } + }, + "validationData": { + "description": "Special validation or data may be required when delivering CDN to some regions due to local compliance reasons. E.g. ICP license number of a custom domain is required to deliver content in China.", + "type": "string" + }, + "provisioningState": { + "readOnly": true, + "description": "Provisioning status of the custom domain.", + "type": "string" + } + } + }, + "CustomDomainParameters": { + "description": "The customDomain JSON object required for custom domain creation or update.", + "type": "object", + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/CustomDomainPropertiesParameters" + } + } + }, + "CustomDomainPropertiesParameters": { + "description": "The JSON object that contains the properties of the custom domain to create.", + "required": ["hostName"], + "properties": { + "hostName": { + "description": "The host name of the custom domain. Must be a domain name.", + "type": "string" + } + } + }, + "CustomDomainListResult": { + "description": "Result of the request to list custom domains. It contains a list of custom domain objects and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/CustomDomain" + }, + "description": "List of CDN CustomDomains within an endpoint." + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of custom domain objects if there are any." + } + } + }, + "ValidateCustomDomainInput": { + "description": "Input of the custom domain to be validated for DNS mapping.", + "type": "object", + "required": ["hostName"], + "properties": { + "hostName": { + "description": "The host name of the custom domain. Must be a domain name.", + "type": "string" + } + } + }, + "ValidateCustomDomainOutput": { + "description": "Output of custom domain validation.", + "type": "object", + "properties": { + "customDomainValidated": { + "description": "Indicates whether the custom domain is valid or not.", + "readOnly": true, + "type": "boolean" + }, + "reason": { + "description": "The reason why the custom domain is not valid.", + "readOnly": true, + "type": "string" + }, + "message": { + "description": "Error message describing why the custom domain is not valid.", + "readOnly": true, + "type": "string" + } + } + }, + "CheckNameAvailabilityInput": { + "description": "Input of CheckNameAvailability API.", + "type": "object", + "required": ["name", "type"], + "properties": { + "name": { + "description": "The resource name to validate.", + "type": "string" + }, + "type": { + "description": "The type of the resource whose name is to be validated.", + "$ref": "#/definitions/ResourceType" + } + } + }, + "CheckNameAvailabilityOutput": { + "description": "Output of check name availability API.", + "type": "object", + "properties": { + "nameAvailable": { + "description": "Indicates whether the name is available.", + "readOnly": true, + "type": "boolean" + }, + "reason": { + "description": "The reason why the name is not available.", + "readOnly": true, + "type": "string" + }, + "message": { + "description": "The detailed error message describing why the name is not available.", + "readOnly": true, + "type": "string" + } + } + }, + "ValidateProbeInput": { + "description": "Input of the validate probe API.", + "properties": { + "probeURL": { + "description": "The probe URL to validate.", + "type": "string" + } + }, + "required": ["probeURL"], + "type": "object" + }, + "ValidateProbeOutput": { + "description": "Output of the validate probe API.", + "properties": { + "isValid": { + "description": "Indicates whether the probe URL is accepted or not.", + "readOnly": true, + "type": "boolean" + }, + "errorCode": { + "description": "Specifies the error code when the probe url is not accepted.", + "readOnly": true, + "type": "string" + }, + "message": { + "description": "The detailed error message describing why the probe URL is not accepted.", + "readOnly": true, + "type": "string" + } + }, + "type": "object" + }, + "ResourceUsageListResult": { + "description": "Output of check resource usage API.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/ResourceUsage" + }, + "description": "List of resource usages." + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of custom domain objects if there are any." + } + } + }, + "ResourceUsage": { + "description": "Output of check resource usage API.", + "type": "object", + "properties": { + "resourceType": { + "type": "string", + "readOnly": true, + "description": "Resource type for which the usage is provided." + }, + "unit": { + "type": "string", + "readOnly": true, + "description": "Unit of the usage. e.g. Count." + }, + "currentValue": { + "type": "integer", + "readOnly": true, + "description": "Actual value of usage on the specified resource type." + }, + "limit": { + "type": "integer", + "readOnly": true, + "description": "Quota of the specified resource type." + } + } + }, + "ResourceType": { + "description": "Type of CDN resource used in CheckNameAvailability.", + "enum": ["Microsoft.Cdn/Profiles/Endpoints"], + "type": "string", + "x-ms-enum": { + "name": "ResourceType", + "modelAsString": false + } + }, + "Operation": { + "description": "CDN REST API operation", + "type": "object", + "properties": { + "name": { + "description": "Operation name: {provider}/{resource}/{operation}", + "readOnly": true, + "type": "string" + }, + "display": { + "description": "The object that represents the operation.", + "properties": { + "provider": { + "description": "Service provider: Microsoft.Cdn", + "readOnly": true, + "type": "string" + }, + "resource": { + "description": "Resource on which the operation is performed: Profile, endpoint, etc.", + "readOnly": true, + "type": "string" + }, + "operation": { + "description": "Operation type: Read, write, delete, etc.", + "readOnly": true, + "type": "string" + } + } + } + } + }, + "OperationsListResult": { + "description": "Result of the request to list CDN operations. It contains a list of operations and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/Operation" + }, + "description": "List of CDN operations supported by the CDN resource provider." + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of operation list results if there are any." + } + } + }, + "EdgenodeResult": { + "description": "Result of the request to list CDN edgenodes. It contains a list of ip address group and a URL link to get the next set of results.", + "properties": { + "value": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/definitions/EdgeNode" + }, + "description": "Edge node of CDN service." + }, + "nextLink": { + "type": "string", + "description": "URL to get the next set of edgenode list results if there are any." + } + } + }, + "EdgeNode": { + "description": "Edgenode is a global Point of Presence (POP) location used to deliver CDN content to end users.", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ProxyResource" + } + ], + "properties": { + "properties": { + "x-ms-client-flatten": true, + "$ref": "#/definitions/EdgeNodeProperties" + } + } + }, + "EdgeNodeProperties": { + "description": "The JSON object that contains the properties required to create an edgenode.", + "required": ["ipAddressGroups"], + "properties": { + "ipAddressGroups": { + "description": "List of ip address groups.", + "type": "array", + "items": { + "$ref": "#/definitions/IpAddressGroup" + } + } + } + }, + "IpAddressGroup": { + "description": "CDN Ip address group", + "type": "object", + "properties": { + "deliveryRegion": { + "description": "The delivery region of the ip address group", + "type": "string" + }, + "ipv4Addresses": { + "description": "The list of ip v4 addresses.", + "type": "array", + "items": { + "$ref": "#/definitions/cidrIpAddress" + } + }, + "ipv6Addresses": { + "description": "The list of ip v6 addresses.", + "type": "array", + "items": { + "$ref": "#/definitions/cidrIpAddress" + } + } + } + }, + "cidrIpAddress": { + "description": "CIDR Ip address", + "type": "object", + "properties": { + "baseIpAddress": { + "description": "IP address itself.", + "type": "string" + }, + "prefixLength": { + "description": "The length of the prefix of the ip address.", + "type": "integer" + } + } + }, + "Resource": { + "description": "The core properties of ARM resources", + "properties": { + "id": { + "description": "Resource ID.", + "readOnly": true, + "type": "string" + }, + "name": { + "description": "Resource name.", + "readOnly": true, + "type": "string" + }, + "type": { + "description": "Resource type.", + "readOnly": true, + "type": "string" + } + }, + "x-ms-azure-resource": true + }, + "TrackedResource": { + "description": "The resource model definition for a ARM tracked top level resource.", + "allOf": [ + { + "$ref": "#/definitions/Resource" + } + ], + "properties": { + "location": { + "type": "string", + "description": "Resource location." + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-ms-mutability": ["read", "create", "update"], + "description": "Resource tags." + } + }, + "required": ["location"] + }, + "ProxyResource": { + "description": "The resource model definition for a ARM proxy resource. It will have everything other than required location and tags", + "allOf": [ + { + "$ref": "#/definitions/Resource" + } + ] + }, + "QueryStringCachingBehavior": { + "description": "Defines how CDN caches requests that include query strings. You can ignore any query strings when caching, bypass caching to prevent requests that contain query strings from being cached, or cache every request with a unique URL.", + "enum": ["IgnoreQueryString", "BypassCaching", "UseQueryString", "NotSet"], + "type": "string", + "x-ms-enum": { + "name": "QueryStringCachingBehavior", + "modelAsString": false + } + }, + "Sku": { + "description": "The pricing tier (defines a CDN provider, feature list and rate) of the CDN profile.", + "properties": { + "name": { + "description": "Name of the pricing tier.", + "enum": [ + "Standard_Verizon", + "Premium_Verizon", + "Custom_Verizon", + "Standard_Akamai", + "Standard_ChinaCdn" + ], + "type": "string", + "x-ms-enum": { + "name": "SkuName", + "modelAsString": true + } + } + }, + "type": "object" + }, + "OptimizationType": { + "description": "Specifies what scenario the customer wants this CDN endpoint to optimize, e.g. Download, Media services. With this information we can apply scenario driven optimization.", + "enum": [ + "GeneralWebDelivery", + "GeneralMediaStreaming", + "VideoOnDemandMediaStreaming", + "LargeFileDownload", + "DynamicSiteAcceleration" + ], + "type": "string", + "x-ms-enum": { + "name": "OptimizationType", + "modelAsString": true + } + }, + "ErrorResponse": { + "description": "Error response indicates CDN service is not able to process the incoming request. The reason is provided in the error message.", + "type": "object", + "properties": { + "code": { + "description": "Error code.", + "readOnly": true, + "type": "string" + }, + "message": { + "description": "Error message indicating why the operation failed.", + "readOnly": true, + "type": "string" + } + } + } + }, + "parameters": { + "subscriptionIdParameter": { + "name": "subscriptionId", + "in": "path", + "description": "Azure Subscription ID.", + "required": true, + "type": "string" + }, + "apiVersionParameter": { + "name": "api-version", + "in": "query", + "required": true, + "type": "string", + "description": "Version of the API to be used with the client request. Current version is 2017-04-02." + }, + "resourceGroupNameParameter": { + "name": "resourceGroupName", + "in": "path", + "required": true, + "type": "string", + "pattern": "^[-\\w\\._\\(\\)]+$", + "minLength": 1, + "maxLength": 90, + "x-ms-parameter-location": "method", + "description": "Name of the Resource group within the Azure subscription." + } + } +} diff --git a/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Create.json b/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Create.json new file mode 100644 index 00000000..3b29907e --- /dev/null +++ b/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Create.json @@ -0,0 +1,67 @@ +{ + "parameters": { + "api-version": "2017-04-02", + "subscriptionId": "subid", + "resourceGroupName": "RG", + "profileName": "profile1", + "profile": { + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": "Creating" + } + } + }, + "responses": { + "200": { + "body": { + "name": "profile1", + "id": "/subscriptions/subid/resourcegroups/RG/providers/Microsoft.Cdn/profiles/profile1", + "type": "Microsoft.Cdn/profiles", + "tags": {}, + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": "Creating", + "resourceState": "Creating" + } + } + }, + "201": { + "body": { + "name": "profile1", + "id": "/subscriptions/subid/resourcegroups/RG/providers/Microsoft.Cdn/profiles/profile1", + "type": "Microsoft.Cdn/profiles", + "tags": {}, + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": "Creating", + "resourceState": "Creating" + } + } + }, + "202": { + "body": { + "name": "profile1", + "id": "/subscriptions/subid/resourcegroups/RG/providers/Microsoft.Cdn/profiles/profile1", + "type": "Microsoft.Cdn/profiles", + "tags": {}, + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": "Creating", + "resourceState": "Creating" + } + } + } + } +} diff --git a/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Update.json b/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Update.json new file mode 100644 index 00000000..01127bb1 --- /dev/null +++ b/test/modelValidation/swaggers/specification/validateReadOnly/examples/Profiles_Update.json @@ -0,0 +1,35 @@ +{ + "parameters": { + "api-version": "2017-04-02", + "subscriptionId": "subid", + "resourceGroupName": "RG", + "profileName": "profile1", + "profile": { + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": 5 + } + } + }, + "responses": { + "200": { + "body": { + "name": "profile1", + "id": "/subscriptions/subid/resourcegroups/RG/providers/Microsoft.Cdn/profiles/profile1", + "type": "Microsoft.Cdn/profiles", + "tags": {}, + "location": "WestCentralUs", + "sku": { + "name": "Standard_Verizon" + }, + "properties": { + "provisioningState": "Creating", + "resourceState": "Creating" + } + } + } + } +} diff --git a/test/readOnlyValidationTests.ts b/test/readOnlyValidationTests.ts new file mode 100644 index 00000000..1f8f9b40 --- /dev/null +++ b/test/readOnlyValidationTests.ts @@ -0,0 +1,48 @@ +import * as assert from "assert" + +import * as validate from "../lib/validate" + +const specPath = `test/modelValidation/swaggers/specification/validateReadOnly/cdn.json` + +describe("Read Only properties", () => { + it("should throw the error with correct code and message", async () => { + const result = await validate.validateExamples(specPath, "Profiles_Create", { + consoleLogLevel: "off" + }) + assert.strictEqual( + result.length, + 1, + `swagger "${specPath}" with operation should contain 1 model validation errors.` + ) + assert.strictEqual( + result[0].code === "READONLY_PROPERTY_NOT_ALLOWED_IN_REQUEST", + true, + `swagger "${specPath}" should throw an error with code READONLY_PROPERTY_NOT_ALLOWED_IN_REQUEST` + ) + assert.equal( + 'ReadOnly property `"provisioningState": "Creating"`, cannot be sent in the request.', + result[0].details!.message + ) + }) + + it("should throw 2 errors - readonly properties not allowed in request and invalid type", async () => { + const result = await validate.validateExamples(specPath, "Profiles_Update", { + consoleLogLevel: "off" + }) + assert.strictEqual( + result.length, + 2, + `swagger "${specPath}" with operation should contain 2 model validation errors.` + ) + assert.strictEqual( + result[0].code === "READONLY_PROPERTY_NOT_ALLOWED_IN_REQUEST", + true, + `swagger "${specPath}" should throw an error with code READONLY_PROPERTY_NOT_ALLOWED_IN_REQUEST` + ) + assert.strictEqual( + result[1].code === "INVALID_TYPE", + true, + `swagger "${specPath}" should throw an error with code READONLY_PROPERTY_NOT_ALLOWED_IN_REQUEST` + ) + }) +})