Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 9314855

Browse files
committed
add yml file arguments for apiVersionSet and authenticationSettings
1 parent b3fe21b commit 9314855

File tree

7 files changed

+136
-73
lines changed

7 files changed

+136
-73
lines changed

src/APIM_ARMTemplate/apimtemplate/Commands/Create.cs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public CreateCommand()
2626
CommandOption apiRevisionDescription = this.Option("--apiRevisionDescription <apiVersionSetId>", "Description of the API revision", CommandOptionType.SingleValue);
2727
CommandOption apiVersion = this.Option("--apiVersion <apiVersion>", "API version", CommandOptionType.SingleValue);
2828
CommandOption apiVersionDescription = this.Option("--apiVersionDescription <apiVersionSetId>", "Description of the API version", CommandOptionType.SingleValue);
29-
CommandOption apiVersionSet = this.Option("--apiVersionSet <apiVersionSetId>", "Serialized JSON object that follows the ApiVersionSetContractDetails object schema - https://docs.microsoft.com/en-us/azure/templates/microsoft.apimanagement/2018-06-01-preview/service/apis#ApiVersionSetContractDetails", CommandOptionType.SingleValue);
29+
CommandOption apiVersionSetFile = this.Option("--apiVersionSetFile <apiVersionSetId>", "YAML file with object that follows the ApiVersionSetContractDetails object schema - https://docs.microsoft.com/en-us/azure/templates/microsoft.apimanagement/2018-06-01-preview/service/apis#ApiVersionSetContractDetails", CommandOptionType.SingleValue);
30+
CommandOption authenticationSettingsFile = this.Option("--authenticationSettingsFile <apiVersionSetId>", "YAML file with object that follows the AuthenticationSettingsContract object schema - https://docs.microsoft.com/en-us/azure/templates/microsoft.apimanagement/2018-06-01-preview/service/apis#AuthenticationSettingsContract", CommandOptionType.SingleValue);
3031
CommandOption apiVersionSetId = this.Option("--apiVersionSetId <apiVersionSetId>", "API version set id", CommandOptionType.SingleValue);
3132
CommandOption productIds = this.Option("--productIds <productIds>", "Product ids to associate the API with", CommandOptionType.MultipleValue);
3233

@@ -51,21 +52,28 @@ public CreateCommand()
5152
apiRevisionDescription = apiRevisionDescription.Value(),
5253
apiVersion = apiVersion.Value(),
5354
apiVersionDescription = apiVersionDescription.Value(),
54-
apiVersionSet = apiVersionSet.Value(),
55+
apiVersionSetFile = apiVersionSetFile.Value(),
5556
apiVersionSetId = apiVersionSetId.Value(),
57+
authenticationSettingsFile = authenticationSettingsFile.Value(),
5658
productIds = productIds.Values
5759
};
5860

59-
if (apiVersionSet.HasValue() && AttemptAPIVersionSetConversion(cliArguments) != null)
61+
if (apiVersionSetFile.HasValue() && AttemptAPIVersionSetConversion(cliArguments) != null)
6062
{
6163
// unable to convert version set argument into object, would cause failure down the line
62-
ColoredConsole.Error.WriteLine("Incorrect API Version Set object structure");
64+
ColoredConsole.Error.WriteLine("Incorrect apiVersionSet object structure");
65+
return 0;
66+
}
67+
else if (authenticationSettingsFile.HasValue() && AttemptAuthenticationSettingsConversion(cliArguments) != null)
68+
{
69+
// unable to convert version set argument into object, would cause failure down the line
70+
ColoredConsole.Error.WriteLine("Incorrect authenticationSettings object structure");
6371
return 0;
6472
}
6573
else
6674
{
6775
// required parameters have been supplied and versionSet has correct object structure
68-
76+
6977
// initialize helper classes
7078
OpenAPISpecReader openAPISpecReader = new OpenAPISpecReader();
7179
ARMTemplateWriter armTemplateWriter = new ARMTemplateWriter();
@@ -111,7 +119,22 @@ public Exception AttemptAPIVersionSetConversion(CLICreatorArguments cliArguments
111119
{
112120
try
113121
{
114-
JsonConvert.DeserializeObject<APITemplateVersionSet>(cliArguments.apiVersionSet);
122+
YAMLReader yamlReader = new YAMLReader();
123+
APITemplateVersionSet versionSet = yamlReader.ConvertYAMLFileToAPIVersionSet(cliArguments.apiVersionSetFile);
124+
return null;
125+
}
126+
catch (Exception ex)
127+
{
128+
return ex;
129+
}
130+
}
131+
132+
public Exception AttemptAuthenticationSettingsConversion(CLICreatorArguments cliArguments)
133+
{
134+
try
135+
{
136+
YAMLReader yamlReader = new YAMLReader();
137+
APITemplateAuthenticationSettings authenticationSettings = yamlReader.ConvertYAMLFileToAuthenticationSettings(cliArguments.authenticationSettingsFile);
115138
return null;
116139
}
117140
catch (Exception ex)

src/APIM_ARMTemplate/apimtemplate/Common/CLIArguments.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ public class CLICreatorArguments
1515
public string path { get; set; }
1616
public string apiVersion { get; set; }
1717
public string apiVersionDescription { get; set; }
18-
public string apiVersionSet { get; set; }
18+
public string apiVersionSetFile { get; set; }
1919
public string apiVersionSetId { get; set; }
2020
public string apiRevision { get; set; }
2121
public string apiRevisionDescription { get; set; }
22+
public string authenticationSettingsFile { get; set; }
2223
public List<string> productIds { get; set; }
2324
}
2425
}

src/APIM_ARMTemplate/apimtemplate/FileHandlers/OpenAPISpecReader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public OpenApiDocument ConvertToOpenAPISpec(string json)
1717
return doc;
1818
}
1919

20-
public OpenApiDocument ConvertLocalFileToOpenAPISpec(string jsonFile)
20+
public OpenApiDocument ConvertLocalFileToOpenAPISpec(string jsonFileLocation)
2121
{
22-
JObject jObject = JObject.Parse(File.ReadAllText(jsonFile));
22+
JObject jObject = JObject.Parse(File.ReadAllText(jsonFileLocation));
2323
string json = JsonConvert.SerializeObject(jObject);
2424
OpenApiDocument document = ConvertToOpenAPISpec(json);
2525
return document;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Microsoft.OpenApi.Models;
2+
using Microsoft.OpenApi.Readers;
3+
using Newtonsoft.Json;
4+
using Newtonsoft.Json.Linq;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Net.Http;
9+
using System.Threading.Tasks;
10+
using YamlDotNet.RepresentationModel;
11+
using YamlDotNet.Serialization;
12+
13+
namespace Microsoft.Azure.Management.ApiManagement.ArmTemplates
14+
{
15+
public class YAMLReader
16+
{
17+
public APITemplateAuthenticationSettings ConvertYAMLFileToAuthenticationSettings(string yamlFileLocation)
18+
{
19+
APITemplateAuthenticationSettings authenticationSettings = new APITemplateAuthenticationSettings();
20+
// Setup the input
21+
StreamReader streamReader = new StreamReader(yamlFileLocation);
22+
// Load the stream
23+
YamlStream yaml = new YamlStream();
24+
yaml.Load(streamReader);
25+
// Examine the stream
26+
YamlMappingNode mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
27+
foreach (var entry in mapping.Children)
28+
{
29+
string key = ((YamlScalarNode)entry.Key).Value;
30+
if (key == "authenticationSettings")
31+
{
32+
YamlMappingNode node = (YamlMappingNode)entry.Value;
33+
// find the the values from the YAML and set the corresponding properties on the version set object
34+
authenticationSettings.subscriptionKeyRequired = (string)node.Children.First(child => (string)child.Key == "subscriptionKeyRequired").Value == "true" ? true : false;
35+
authenticationSettings.oAuth2 = new APITemplateOAuth2();
36+
authenticationSettings.openid = new APITemplateOpenID();
37+
foreach (var child in node.Children)
38+
{
39+
string childKey = ((YamlScalarNode)child.Key).Value;
40+
if (childKey == "oAuth2")
41+
{
42+
YamlMappingNode childNode = (YamlMappingNode)child.Value;
43+
// find the the values from the YAML and set the corresponding properties on the version set object
44+
authenticationSettings.oAuth2.authorizationServerId = (string)childNode.Children.First(c => (string)c.Key == "authorizationServerId").Value;
45+
authenticationSettings.oAuth2.scope = (string)childNode.Children.First(c => (string)c.Key == "scope").Value;
46+
} else if (childKey == "openid")
47+
{
48+
YamlMappingNode childNode = (YamlMappingNode)child.Value;
49+
// find the the values from the YAML and set the corresponding properties on the version set object
50+
authenticationSettings.openid.openidProviderId = (string)childNode.Children.First(c => (string)c.Key == "openidProviderId").Value;
51+
List<string> methods = new List<string>();
52+
foreach (var subChild in childNode.Children)
53+
{
54+
string subkey = ((YamlScalarNode)subChild.Key).Value;
55+
if(subkey == "bearerTokenSendingMethods")
56+
{
57+
YamlSequenceNode subChildNode = (YamlSequenceNode)subChild.Value;
58+
foreach(YamlScalarNode deepChild in subChildNode.Children)
59+
{
60+
methods.Add(deepChild.Value);
61+
}
62+
}
63+
}
64+
authenticationSettings.openid.bearerTokenSendingMethods = methods.ToArray();
65+
}
66+
}
67+
}
68+
}
69+
return authenticationSettings;
70+
}
71+
public APITemplateVersionSet ConvertYAMLFileToAPIVersionSet(string yamlFileLocation)
72+
{
73+
APITemplateVersionSet apiVersionSet = new APITemplateVersionSet();
74+
// Setup the input
75+
StreamReader streamReader = new StreamReader(yamlFileLocation);
76+
// Load the stream
77+
YamlStream yaml = new YamlStream();
78+
yaml.Load(streamReader);
79+
// Examine the stream
80+
YamlMappingNode mapping = (YamlMappingNode)yaml.Documents[0].RootNode;
81+
foreach (var entry in mapping.Children)
82+
{
83+
string key = ((YamlScalarNode)entry.Key).Value;
84+
if (key == "apiVersionSet")
85+
{
86+
YamlMappingNode node = (YamlMappingNode)entry.Value;
87+
// find the the values from the YAML and set the corresponding properties on the version set object
88+
apiVersionSet.id = (string)node.Children.First(child => (string)child.Key == "id").Value;
89+
apiVersionSet.description = (string)node.Children.First(child => (string)child.Key == "description").Value;
90+
apiVersionSet.versionHeaderName = (string)node.Children.First(child => (string)child.Key == "versionHeaderName").Value;
91+
apiVersionSet.versioningScheme = (string)node.Children.First(child => (string)child.Key == "versioningScheme").Value;
92+
apiVersionSet.versionQueryName = (string)node.Children.First(child => (string)child.Key == "versionQueryName").Value;
93+
}
94+
}
95+
return apiVersionSet;
96+
}
97+
}
98+
}

src/APIM_ARMTemplate/apimtemplate/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"profiles": {
33
"apimtemplate": {
44
"commandName": "Project",
5-
"commandLineArgs": "create --outputLocation=\"C:\\Users\\lucashh\\Desktop\\Projects\\APIM-ARM\\GeneratedTemplates\" --openAPISpecFile=\"C:\\Users\\lucashh\\Desktop\\Projects\\APIM-ARM\\ExampleSpecs\\tags.json\" --apiVersionSet=\"\"{\\\"id\\\":\\\"1\\\",\\\"description\\\":\\\"d\\\",\\\"versioningScheme\\\":\\\"s\\\",\\\"versionQueryName\\\":\\\"q\\\",\\\"versionHeaderName\\\":\\\"v\\\"}\"\""
5+
"commandLineArgs": "create --outputLocation=\"C:\\Users\\lucashh\\Desktop\\Projects\\APIM-ARM\\GeneratedTemplates\" --openAPISpecFile=\"C:\\Users\\lucashh\\Desktop\\Projects\\APIM-ARM\\ExampleInputs\\openAPISpecs\\tags.json\" --apiVersionSetFile=\"C:\\Users\\lucashh\\Desktop\\Projects\\APIM-ARM\\ExampleInputs\\apiVersionSets\\valid.yml\""
66
}
77
}
88
}

src/APIM_ARMTemplate/apimtemplate/TemplateCreators/APITemplateCreator.cs

Lines changed: 3 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class APITemplateCreator
1212
{
1313
public async Task<APITemplate> CreateAPITemplateAsync(OpenApiDocument doc, CLICreatorArguments cliArguments)
1414
{
15+
YAMLReader yamlReader = new YAMLReader();
1516
// create api schema with properties
1617
APITemplate apiSchema = new APITemplate()
1718
{
@@ -34,8 +35,8 @@ public async Task<APITemplate> CreateAPITemplateAsync(OpenApiDocument doc, CLICr
3435
path = cliArguments.path ?? "",
3536
apiRevisionDescription = cliArguments.apiRevisionDescription ?? "",
3637
apiVersionDescription = cliArguments.apiVersionDescription ?? "",
37-
apiVersionSet = cliArguments.apiVersionSet != null ? JsonConvert.DeserializeObject<APITemplateVersionSet>(cliArguments.apiVersionSet) : null,
38-
authenticationSettings = CreateAuthenticationSettings(doc),
38+
apiVersionSet = cliArguments.apiVersionSetFile != null ? yamlReader.ConvertYAMLFileToAPIVersionSet(cliArguments.apiVersionSetFile) : null,
39+
authenticationSettings = cliArguments.authenticationSettingsFile != null ? yamlReader.ConvertYAMLFileToAuthenticationSettings(cliArguments.authenticationSettingsFile) : null,
3940
// assumptions
4041
type = "http",
4142
apiType = "http",
@@ -56,67 +57,6 @@ public async Task<APITemplate> CreateAPITemplateAsync(OpenApiDocument doc, CLICr
5657
return apiSchema;
5758
}
5859

59-
public APITemplateAuthenticationSettings CreateAuthenticationSettings(OpenApiDocument doc)
60-
{
61-
// initialize subscriptionKeyRequired with value from IsSubscriptionRequired
62-
APITemplateAuthenticationSettings authenticationSettings = new APITemplateAuthenticationSettings()
63-
{
64-
subscriptionKeyRequired = IsSubscriptionRequired(doc)
65-
};
66-
foreach (OpenApiSecurityScheme securityScheme in doc.Components.SecuritySchemes.Values)
67-
{
68-
if (securityScheme.Type == SecuritySchemeType.OAuth2)
69-
{
70-
authenticationSettings.oAuth2 = CreateOAuth2(securityScheme);
71-
}
72-
else if (securityScheme.Type == SecuritySchemeType.OpenIdConnect)
73-
{
74-
// the bearer format property only appears in Open API specs for SecuritySchemeType.Http and will never appear for OpenIDConnect
75-
authenticationSettings.openid = new APITemplateOpenID()
76-
{
77-
openidProviderId = securityScheme.OpenIdConnectUrl.ToString(),
78-
bearerTokenSendingMethods = new string[] { }
79-
};
80-
}
81-
else if (securityScheme.Type == SecuritySchemeType.ApiKey)
82-
{
83-
authenticationSettings.subscriptionKeyRequired = true;
84-
}
85-
};
86-
return authenticationSettings;
87-
}
88-
89-
public APITemplateOAuth2 CreateOAuth2(OpenApiSecurityScheme scheme)
90-
{
91-
APITemplateOAuth2 oAuth2 = new APITemplateOAuth2()
92-
{
93-
authorizationServerId = "",
94-
scope = ""
95-
};
96-
// iterate through different flows, set serverId and scope once auth flow is found
97-
if (scheme.Flows.Implicit != null)
98-
{
99-
oAuth2.authorizationServerId = scheme.Flows.Implicit.AuthorizationUrl != null ? scheme.Flows.Implicit.AuthorizationUrl.ToString() : "";
100-
oAuth2.scope = scheme.Flows.Implicit.Scopes != null && scheme.Flows.Implicit.Scopes.Keys.FirstOrDefault() != null ? oAuth2.scope = scheme.Flows.Implicit.Scopes.Keys.FirstOrDefault() : "";
101-
}
102-
else if (scheme.Flows.AuthorizationCode != null)
103-
{
104-
oAuth2.authorizationServerId = scheme.Flows.AuthorizationCode.AuthorizationUrl != null ? scheme.Flows.AuthorizationCode.AuthorizationUrl.ToString() : "";
105-
oAuth2.scope = scheme.Flows.AuthorizationCode.Scopes != null && scheme.Flows.AuthorizationCode.Scopes.Keys.FirstOrDefault() != null ? oAuth2.scope = scheme.Flows.AuthorizationCode.Scopes.Keys.FirstOrDefault() : "";
106-
}
107-
else if (scheme.Flows.ClientCredentials != null)
108-
{
109-
oAuth2.authorizationServerId = scheme.Flows.ClientCredentials.AuthorizationUrl != null ? scheme.Flows.ClientCredentials.AuthorizationUrl.ToString() : "";
110-
oAuth2.scope = scheme.Flows.ClientCredentials.Scopes != null && scheme.Flows.ClientCredentials.Scopes.Keys.FirstOrDefault() != null ? oAuth2.scope = scheme.Flows.ClientCredentials.Scopes.Keys.FirstOrDefault() : "";
111-
}
112-
else if (scheme.Flows.Password != null)
113-
{
114-
oAuth2.authorizationServerId = scheme.Flows.Password.AuthorizationUrl != null ? scheme.Flows.Password.AuthorizationUrl.ToString() : "";
115-
oAuth2.scope = scheme.Flows.Password.Scopes != null && scheme.Flows.Password.Scopes.Keys.FirstOrDefault() != null ? oAuth2.scope = scheme.Flows.Password.Scopes.Keys.FirstOrDefault() : "";
116-
}
117-
return oAuth2;
118-
}
119-
12060
public async Task<string> CreateOpenAPISpecContentsAsync(CLICreatorArguments cliArguments)
12161
{
12262
// return contents of supplied Open API Spec file

src/APIM_ARMTemplate/apimtemplate/apimtemplate.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<PackageReference Include="Microsoft.OpenApi" Version="1.1.1" />
1212
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.1.1" />
1313
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
14+
<PackageReference Include="YamlDotNet" Version="5.3.0" />
1415
</ItemGroup>
1516

1617
</Project>

0 commit comments

Comments
 (0)