diff --git a/DDNSUpdater.sln b/DDNSUpdater.sln index 2a75291..c76a30f 100644 --- a/DDNSUpdater.sln +++ b/DDNSUpdater.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DDNSUpdater", "DDNSUpdater\DDNSUpdater.csproj", "{EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2F1B5788-B2D6-43B9-A523-5D308F33279C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDEDF642-4CFC-4EEB-A8F2-3872DBEC63E3}.Release|Any CPU.Build.0 = Release|Any CPU + {2F1B5788-B2D6-43B9-A523-5D308F33279C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F1B5788-B2D6-43B9-A523-5D308F33279C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F1B5788-B2D6-43B9-A523-5D308F33279C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F1B5788-B2D6-43B9-A523-5D308F33279C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/DDNSUpdater/APIs/GRPC/Grpc.cs b/DDNSUpdater/APIs/GRPC/Grpc.cs new file mode 100644 index 0000000..ef35aab --- /dev/null +++ b/DDNSUpdater/APIs/GRPC/Grpc.cs @@ -0,0 +1,6 @@ +namespace DDNSUpdater.APIs.GRPC; + +public class Grpc +{ + //This is where the GRPC Server for Communication between Services should come +} \ No newline at end of file diff --git a/DDNSUpdater/APIs/Ionos/IonosAPIClient.cs b/DDNSUpdater/APIs/Ionos/IonosAPIClient.cs new file mode 100644 index 0000000..75ef1fc --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/IonosAPIClient.cs @@ -0,0 +1,48 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.V1; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Extensions; +using Microsoft.Kiota.Serialization.Form; +using Microsoft.Kiota.Serialization.Json; +using Microsoft.Kiota.Serialization.Text; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient { + /// + /// The main entry point of the SDK, exposes the configuration and the fluent API. + /// + public class IonosAPIClient { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// The v1 property + public V1RequestBuilder V1 { get => + new V1RequestBuilder(PathParameters, RequestAdapter); + } + /// + /// Instantiates a new IonosAPIClient and sets the default values. + /// + /// The request adapter to use to execute the requests. + public IonosAPIClient(IRequestAdapter requestAdapter) { + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + PathParameters = new Dictionary(); + UrlTemplate = "{+baseurl}"; + RequestAdapter = requestAdapter; + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultSerializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + ApiClientBuilder.RegisterDefaultDeserializer(); + if (string.IsNullOrEmpty(RequestAdapter.BaseUrl)) { + RequestAdapter.BaseUrl = "https://api.hosting.ionos.com/dns"; + } + PathParameters.TryAdd("baseurl", RequestAdapter.BaseUrl); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/CustomerZone.cs b/DDNSUpdater/APIs/Ionos/Models/CustomerZone.cs new file mode 100644 index 0000000..7307494 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/CustomerZone.cs @@ -0,0 +1,74 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class CustomerZone : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The zone id. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Id { get; set; } +#nullable restore +#else + public string Id { get; set; } +#endif + /// The zone name +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Name { get; set; } +#nullable restore +#else + public string Name { get; set; } +#endif + /// The records property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? Records { get; set; } +#nullable restore +#else + public List Records { get; set; } +#endif + /// Represents the possible zone types. + public ZoneTypes? Type { get; set; } + /// + /// Instantiates a new CustomerZone and sets the default values. + /// + public CustomerZone() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static CustomerZone CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new CustomerZone(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"id", n => { Id = n.GetStringValue(); } }, + {"name", n => { Name = n.GetStringValue(); } }, + {"records", n => { Records = n.GetCollectionOfObjectValues(RecordResponse.CreateFromDiscriminatorValue)?.ToList(); } }, + {"type", n => { Type = n.GetEnumValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("id", Id); + writer.WriteStringValue("name", Name); + writer.WriteCollectionOfObjectValues("records", Records); + writer.WriteEnumValue("type", Type); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/DynDnsRequest.cs b/DDNSUpdater/APIs/Ionos/Models/DynDnsRequest.cs new file mode 100644 index 0000000..66063df --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/DynDnsRequest.cs @@ -0,0 +1,60 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class DynDnsRequest : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// Dynamic Dns description. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Description { get; set; } +#nullable restore +#else + public string Description { get; set; } +#endif + /// The domains property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? Domains { get; set; } +#nullable restore +#else + public List Domains { get; set; } +#endif + /// + /// Instantiates a new DynDnsRequest and sets the default values. + /// + public DynDnsRequest() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static DynDnsRequest CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new DynDnsRequest(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"description", n => { Description = n.GetStringValue(); } }, + {"domains", n => { Domains = n.GetCollectionOfPrimitiveValues()?.ToList(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("description", Description); + writer.WriteCollectionOfPrimitiveValues("domains", Domains); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/DynamicDns.cs b/DDNSUpdater/APIs/Ionos/Models/DynamicDns.cs new file mode 100644 index 0000000..f434114 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/DynamicDns.cs @@ -0,0 +1,80 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class DynamicDns : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// DynDns configuration identifier. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? BulkId { get; set; } +#nullable restore +#else + public string BulkId { get; set; } +#endif + /// Dynamic Dns description. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Description { get; set; } +#nullable restore +#else + public string Description { get; set; } +#endif + /// The domains property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? Domains { get; set; } +#nullable restore +#else + public List Domains { get; set; } +#endif + /// Use the url with GET to update the ips of (sub)domains. Query parameters: ipv4, ipv6. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? UpdateUrl { get; set; } +#nullable restore +#else + public string UpdateUrl { get; set; } +#endif + /// + /// Instantiates a new DynamicDns and sets the default values. + /// + public DynamicDns() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static DynamicDns CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new DynamicDns(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"bulkId", n => { BulkId = n.GetStringValue(); } }, + {"description", n => { Description = n.GetStringValue(); } }, + {"domains", n => { Domains = n.GetCollectionOfPrimitiveValues()?.ToList(); } }, + {"updateUrl", n => { UpdateUrl = n.GetStringValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("bulkId", BulkId); + writer.WriteStringValue("description", Description); + writer.WriteCollectionOfPrimitiveValues("domains", Domains); + writer.WriteStringValue("updateUrl", UpdateUrl); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/Error.cs b/DDNSUpdater/APIs/Ionos/Models/Error.cs new file mode 100644 index 0000000..29f5730 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/Error.cs @@ -0,0 +1,61 @@ +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class Error : ApiException, IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The error code. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Code { get; set; } +#nullable restore +#else + public string Code { get; set; } +#endif + /// The error message. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? MessageEscaped { get; set; } +#nullable restore +#else + public string MessageEscaped { get; set; } +#endif + /// + /// Instantiates a new Error and sets the default values. + /// + public Error() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static Error CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new Error(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"code", n => { Code = n.GetStringValue(); } }, + {"message", n => { MessageEscaped = n.GetStringValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("code", Code); + writer.WriteStringValue("message", MessageEscaped); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/Record.cs b/DDNSUpdater/APIs/Ionos/Models/Record.cs new file mode 100644 index 0000000..a5ae8c5 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/Record.cs @@ -0,0 +1,76 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class Record : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The content property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Content { get; set; } +#nullable restore +#else + public string Content { get; set; } +#endif + /// When is true, the record is not visible for lookup. + public bool? Disabled { get; set; } + /// The name property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Name { get; set; } +#nullable restore +#else + public string Name { get; set; } +#endif + /// The prio property + public int? Prio { get; set; } + /// Time to live for the record, recommended 3600. + public int? Ttl { get; set; } + /// Holds supported dns record types. + public RecordTypes? Type { get; set; } + /// + /// Instantiates a new record and sets the default values. + /// + public Record() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static Record CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new Record(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"content", n => { Content = n.GetStringValue(); } }, + {"disabled", n => { Disabled = n.GetBoolValue(); } }, + {"name", n => { Name = n.GetStringValue(); } }, + {"prio", n => { Prio = n.GetIntValue(); } }, + {"ttl", n => { Ttl = n.GetIntValue(); } }, + {"type", n => { Type = n.GetEnumValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("content", Content); + writer.WriteBoolValue("disabled", Disabled); + writer.WriteStringValue("name", Name); + writer.WriteIntValue("prio", Prio); + writer.WriteIntValue("ttl", Ttl); + writer.WriteEnumValue("type", Type); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/RecordResponse.cs b/DDNSUpdater/APIs/Ionos/Models/RecordResponse.cs new file mode 100644 index 0000000..a33fdcf --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/RecordResponse.cs @@ -0,0 +1,107 @@ +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class RecordResponse : ApiException, IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The date of the last change formatted as yyyy-MM-dd'T'HH:mm:ss.SSS'Z' +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? ChangeDate { get; set; } +#nullable restore +#else + public string ChangeDate { get; set; } +#endif + /// The content property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Content { get; set; } +#nullable restore +#else + public string Content { get; set; } +#endif + /// When is true, the record is not visible for lookup. + public bool? Disabled { get; set; } + /// The id property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Id { get; set; } +#nullable restore +#else + public string Id { get; set; } +#endif + /// The name property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Name { get; set; } +#nullable restore +#else + public string Name { get; set; } +#endif + /// The prio property + public int? Prio { get; set; } + /// Root zone name. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? RootName { get; set; } +#nullable restore +#else + public string RootName { get; set; } +#endif + /// Time to live for the record, recommended 3600. + public int? Ttl { get; set; } + /// Holds supported dns record types. + public RecordTypes? Type { get; set; } + /// + /// Instantiates a new recordResponse and sets the default values. + /// + public RecordResponse() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static RecordResponse CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new RecordResponse(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"changeDate", n => { ChangeDate = n.GetStringValue(); } }, + {"content", n => { Content = n.GetStringValue(); } }, + {"disabled", n => { Disabled = n.GetBoolValue(); } }, + {"id", n => { Id = n.GetStringValue(); } }, + {"name", n => { Name = n.GetStringValue(); } }, + {"prio", n => { Prio = n.GetIntValue(); } }, + {"rootName", n => { RootName = n.GetStringValue(); } }, + {"ttl", n => { Ttl = n.GetIntValue(); } }, + {"type", n => { Type = n.GetEnumValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("changeDate", ChangeDate); + writer.WriteStringValue("content", Content); + writer.WriteBoolValue("disabled", Disabled); + writer.WriteStringValue("id", Id); + writer.WriteStringValue("name", Name); + writer.WriteIntValue("prio", Prio); + writer.WriteStringValue("rootName", RootName); + writer.WriteIntValue("ttl", Ttl); + writer.WriteEnumValue("type", Type); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/RecordTypes.cs b/DDNSUpdater/APIs/Ionos/Models/RecordTypes.cs new file mode 100644 index 0000000..9966adf --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/RecordTypes.cs @@ -0,0 +1,25 @@ +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + /// Holds supported dns record types. + public enum RecordTypes { + A, + AAAA, + CNAME, + MX, + NS, + SOA, + SRV, + TXT, + CAA, + TLSA, + SMIMEA, + SSHFP, + DS, + HTTPS, + SVCB, + CERT, + URI, + RP, + LOC, + OPENPGPKEY, + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/RecordUpdate.cs b/DDNSUpdater/APIs/Ionos/Models/RecordUpdate.cs new file mode 100644 index 0000000..8e0697b --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/RecordUpdate.cs @@ -0,0 +1,62 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class RecordUpdate : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The content property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Content { get; set; } +#nullable restore +#else + public string Content { get; set; } +#endif + /// When is true, the record is not visible for lookup. + public bool? Disabled { get; set; } + /// The prio property + public int? Prio { get; set; } + /// Time to live for the record, recommended 3600. + public int? Ttl { get; set; } + /// + /// Instantiates a new RecordUpdate and sets the default values. + /// + public RecordUpdate() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static RecordUpdate CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new RecordUpdate(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"content", n => { Content = n.GetStringValue(); } }, + {"disabled", n => { Disabled = n.GetBoolValue(); } }, + {"prio", n => { Prio = n.GetIntValue(); } }, + {"ttl", n => { Ttl = n.GetIntValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("content", Content); + writer.WriteBoolValue("disabled", Disabled); + writer.WriteIntValue("prio", Prio); + writer.WriteIntValue("ttl", Ttl); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/WithZone.cs b/DDNSUpdater/APIs/Ionos/Models/WithZone.cs new file mode 100644 index 0000000..0d13b92 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/WithZone.cs @@ -0,0 +1,91 @@ +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class WithZone : ApiException, IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The errorRecord property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public Record? ErrorRecord { get; set; } +#nullable restore +#else + public Record ErrorRecord { get; set; } +#endif + /// The inputRecord property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public Record? InputRecord { get; set; } +#nullable restore +#else + public Record InputRecord { get; set; } +#endif + /// The invalid property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? Invalid { get; set; } +#nullable restore +#else + public List Invalid { get; set; } +#endif + /// The invalidFields property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? InvalidFields { get; set; } +#nullable restore +#else + public List InvalidFields { get; set; } +#endif + /// The requiredFields property +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public List? RequiredFields { get; set; } +#nullable restore +#else + public List RequiredFields { get; set; } +#endif + /// + /// Instantiates a new WithZone and sets the default values. + /// + public WithZone() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static WithZone CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new WithZone(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"errorRecord", n => { ErrorRecord = n.GetObjectValue(Record.CreateFromDiscriminatorValue); } }, + {"inputRecord", n => { InputRecord = n.GetObjectValue(Record.CreateFromDiscriminatorValue); } }, + {"invalid", n => { Invalid = n.GetCollectionOfPrimitiveValues()?.ToList(); } }, + {"invalidFields", n => { InvalidFields = n.GetCollectionOfPrimitiveValues()?.ToList(); } }, + {"requiredFields", n => { RequiredFields = n.GetCollectionOfPrimitiveValues()?.ToList(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteObjectValue("errorRecord", ErrorRecord); + writer.WriteObjectValue("inputRecord", InputRecord); + writer.WriteCollectionOfPrimitiveValues("invalid", Invalid); + writer.WriteCollectionOfPrimitiveValues("invalidFields", InvalidFields); + writer.WriteCollectionOfPrimitiveValues("requiredFields", RequiredFields); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/Zone.cs b/DDNSUpdater/APIs/Ionos/Models/Zone.cs new file mode 100644 index 0000000..7788b0b --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/Zone.cs @@ -0,0 +1,64 @@ +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + public class Zone : IAdditionalDataHolder, IParsable { + /// Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well. + public IDictionary AdditionalData { get; set; } + /// The zone id. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Id { get; set; } +#nullable restore +#else + public string Id { get; set; } +#endif + /// The zone name. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Name { get; set; } +#nullable restore +#else + public string Name { get; set; } +#endif + /// Represents the possible zone types. + public ZoneTypes? Type { get; set; } + /// + /// Instantiates a new Zone and sets the default values. + /// + public Zone() { + AdditionalData = new Dictionary(); + } + /// + /// Creates a new instance of the appropriate class based on discriminator value + /// + /// The parse node to use to read the discriminator value and create the object + public static Zone CreateFromDiscriminatorValue(IParseNode parseNode) { + _ = parseNode ?? throw new ArgumentNullException(nameof(parseNode)); + return new Zone(); + } + /// + /// The deserialization information for the current model + /// + public IDictionary> GetFieldDeserializers() { + return new Dictionary> { + {"id", n => { Id = n.GetStringValue(); } }, + {"name", n => { Name = n.GetStringValue(); } }, + {"type", n => { Type = n.GetEnumValue(); } }, + }; + } + /// + /// Serializes information the current object + /// + /// Serialization writer to use to serialize this model + public void Serialize(ISerializationWriter writer) { + _ = writer ?? throw new ArgumentNullException(nameof(writer)); + writer.WriteStringValue("id", Id); + writer.WriteStringValue("name", Name); + writer.WriteEnumValue("type", Type); + writer.WriteAdditionalData(AdditionalData); + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/Models/ZoneTypes.cs b/DDNSUpdater/APIs/Ionos/Models/ZoneTypes.cs new file mode 100644 index 0000000..55a077e --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/Models/ZoneTypes.cs @@ -0,0 +1,7 @@ +namespace DDNSUpdater.APIs.Ionos.ApiClient.Models { + /// Represents the possible zone types. + public enum ZoneTypes { + NATIVE, + SLAVE, + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Dyndns/DyndnsRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Dyndns/DyndnsRequestBuilder.cs new file mode 100644 index 0000000..662f491 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Dyndns/DyndnsRequestBuilder.cs @@ -0,0 +1,181 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Dyndns.Item; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Dyndns { + /// + /// Builds and executes requests for operations under \v1\dyndns + /// + public class DyndnsRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// Gets an item from the DDNSUpdater.APIs.Ionos.ApiClient.v1.dyndns.item collection + public WithBulkItemRequestBuilder this[string position] { get { + var urlTplParams = new Dictionary(PathParameters); + if (!string.IsNullOrWhiteSpace(position)) urlTplParams.Add("bulkId", position); + return new WithBulkItemRequestBuilder(urlTplParams, RequestAdapter); + } } + /// + /// Instantiates a new DyndnsRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public DyndnsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/dyndns"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new DyndnsRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public DyndnsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/dyndns"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Disable Dynamic Dns.The following quota applies: 2 requests per minute per IP address. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task DeleteAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task DeleteAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToDeleteRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Activate Dynamic Dns for a bundle of (sub)domains. The url from response will be used to update the ips of the (sub)domains.The following quota applies: 2 requests per minute per IP address. + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task PostAsync(DynDnsRequest body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task PostAsync(DynDnsRequest body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPostRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", Error.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendAsync(requestInfo, DynamicDns.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + } + /// + /// Disable Dynamic Dns.The following quota applies: 2 requests per minute per IP address. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToDeleteRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToDeleteRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.DELETE, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + if (requestConfiguration != null) { + var requestConfig = new DyndnsRequestBuilderDeleteRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Activate Dynamic Dns for a bundle of (sub)domains. The url from response will be used to update the ips of the (sub)domains.The following quota applies: 2 requests per minute per IP address. + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPostRequestInformation(DynDnsRequest body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPostRequestInformation(DynDnsRequest body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.POST, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new DyndnsRequestBuilderPostRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class DyndnsRequestBuilderDeleteRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new dyndnsRequestBuilderDeleteRequestConfiguration and sets the default values. + /// + public DyndnsRequestBuilderDeleteRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class DyndnsRequestBuilderPostRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new dyndnsRequestBuilderPostRequestConfiguration and sets the default values. + /// + public DyndnsRequestBuilderPostRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Dyndns/Item/WithBulkItemRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Dyndns/Item/WithBulkItemRequestBuilder.cs new file mode 100644 index 0000000..69742ef --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Dyndns/Item/WithBulkItemRequestBuilder.cs @@ -0,0 +1,175 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Dyndns.Item { + /// + /// Builds and executes requests for operations under \v1\dyndns\{bulkId} + /// + public class WithBulkItemRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// + /// Instantiates a new WithBulkItemRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithBulkItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/dyndns/{bulkId}"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new WithBulkItemRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithBulkItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/dyndns/{bulkId}"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Disable Dynamic Dns for bulk id.The following quota applies: 2 requests per minute per IP address. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task DeleteAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task DeleteAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToDeleteRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Update Dynamic Dns for bulk id.The following quota applies: 2 requests per minute per IP address. + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task PutAsync(DynDnsRequest body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task PutAsync(DynDnsRequest body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPutRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", Error.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"403", Error.CreateFromDiscriminatorValue}, + {"404", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Disable Dynamic Dns for bulk id.The following quota applies: 2 requests per minute per IP address. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToDeleteRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToDeleteRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.DELETE, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + if (requestConfiguration != null) { + var requestConfig = new WithBulkItemRequestBuilderDeleteRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Update Dynamic Dns for bulk id.The following quota applies: 2 requests per minute per IP address. + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPutRequestInformation(DynDnsRequest body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPutRequestInformation(DynDnsRequest body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.PUT, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new WithBulkItemRequestBuilderPutRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithBulkItemRequestBuilderDeleteRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithBulkItemRequestBuilderDeleteRequestConfiguration and sets the default values. + /// + public WithBulkItemRequestBuilderDeleteRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithBulkItemRequestBuilderPutRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithBulkItemRequestBuilderPutRequestConfiguration and sets the default values. + /// + public WithBulkItemRequestBuilderPutRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/V1RequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/V1RequestBuilder.cs new file mode 100644 index 0000000..b8b469d --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/V1RequestBuilder.cs @@ -0,0 +1,56 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Dyndns; +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones; +using Microsoft.Kiota.Abstractions; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1 { + /// + /// Builds and executes requests for operations under \v1 + /// + public class V1RequestBuilder { + /// The dyndns property + public DyndnsRequestBuilder Dyndns { get => + new DyndnsRequestBuilder(PathParameters, RequestAdapter); + } + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// The zones property + public ZonesRequestBuilder Zones { get => + new ZonesRequestBuilder(PathParameters, RequestAdapter); + } + /// + /// Instantiates a new V1RequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public V1RequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new V1RequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public V1RequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/Item/WithRecordItemRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/Item/WithRecordItemRequestBuilder.cs new file mode 100644 index 0000000..c59d7ee --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/Item/WithRecordItemRequestBuilder.cs @@ -0,0 +1,237 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item.Records.Item { + /// + /// Builds and executes requests for operations under \v1\zones\{zoneId}\records\{recordId} + /// + public class WithRecordItemRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// + /// Instantiates a new WithRecordItemRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithRecordItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}/records/{recordId}"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new WithRecordItemRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithRecordItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}/records/{recordId}"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Delete a record from the customer zone. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task DeleteAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task DeleteAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToDeleteRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"404", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Returns the record from the customer zone with the mentioned id. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task GetAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"404", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendAsync(requestInfo, RecordResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + } + /// + /// Update a record from the customer zone. + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task PutAsync(RecordUpdate body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task PutAsync(RecordUpdate body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPutRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", RecordResponse.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"404", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendAsync(requestInfo, RecordResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + } + /// + /// Delete a record from the customer zone. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToDeleteRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToDeleteRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.DELETE, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + if (requestConfiguration != null) { + var requestConfig = new WithRecordItemRequestBuilderDeleteRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Returns the record from the customer zone with the mentioned id. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.GET, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + if (requestConfiguration != null) { + var requestConfig = new WithRecordItemRequestBuilderGetRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Update a record from the customer zone. + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPutRequestInformation(RecordUpdate body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPutRequestInformation(RecordUpdate body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.PUT, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new WithRecordItemRequestBuilderPutRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithRecordItemRequestBuilderDeleteRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithRecordItemRequestBuilderDeleteRequestConfiguration and sets the default values. + /// + public WithRecordItemRequestBuilderDeleteRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithRecordItemRequestBuilderGetRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithRecordItemRequestBuilderGetRequestConfiguration and sets the default values. + /// + public WithRecordItemRequestBuilderGetRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithRecordItemRequestBuilderPutRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithRecordItemRequestBuilderPutRequestConfiguration and sets the default values. + /// + public WithRecordItemRequestBuilderPutRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/RecordsRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/RecordsRequestBuilder.cs new file mode 100644 index 0000000..0a358da --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/Records/RecordsRequestBuilder.cs @@ -0,0 +1,123 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item.Records.Item; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item.Records { + /// + /// Builds and executes requests for operations under \v1\zones\{zoneId}\records + /// + public class RecordsRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// Gets an item from the DDNSUpdater.APIs.Ionos.ApiClient.v1.zones.item.records.item collection + public WithRecordItemRequestBuilder this[string position] { get { + var urlTplParams = new Dictionary(PathParameters); + if (!string.IsNullOrWhiteSpace(position)) urlTplParams.Add("recordId", position); + return new WithRecordItemRequestBuilder(urlTplParams, RequestAdapter); + } } + /// + /// Instantiates a new RecordsRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public RecordsRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}/records"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new RecordsRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public RecordsRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}/records"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Creates records for a customer zone. + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task?> PostAsync(List body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task> PostAsync(List body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPostRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", Error.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + var collectionResult = await RequestAdapter.SendCollectionAsync(requestInfo, RecordResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + return collectionResult?.ToList(); + } + /// + /// Creates records for a customer zone. + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPostRequestInformation(List body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPostRequestInformation(List body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.POST, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new RecordsRequestBuilderPostRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class RecordsRequestBuilderPostRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new recordsRequestBuilderPostRequestConfiguration and sets the default values. + /// + public RecordsRequestBuilderPostRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Zones/Item/WithZoneItemRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/WithZoneItemRequestBuilder.cs new file mode 100644 index 0000000..5ab6522 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Zones/Item/WithZoneItemRequestBuilder.cs @@ -0,0 +1,276 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item.Records; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item { + /// + /// Builds and executes requests for operations under \v1\zones\{zoneId} + /// + public class WithZoneItemRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The records property + public RecordsRequestBuilder Records { get => + new RecordsRequestBuilder(PathParameters, RequestAdapter); + } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// + /// Instantiates a new WithZoneItemRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public WithZoneItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}{?suffix*,recordName*,recordType*}"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new WithZoneItemRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public WithZoneItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones/{zoneId}{?suffix*,recordName*,recordType*}"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Returns a customer zone. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task GetAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendAsync(requestInfo, CustomerZone.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + } + /// + /// Replaces all records of the same name and type with the ones provided. + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task PatchAsync(List body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task PatchAsync(List body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPatchRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", WithZone.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Replaces all records in the zone with the ones provided + /// + /// The request body + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task PutAsync(List body, Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task PutAsync(List body, Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = ToPutRequestInformation(body, requestConfiguration); + var errorMapping = new Dictionary> { + {"400", WithZone.CreateFromDiscriminatorValue}, + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken); + } + /// + /// Returns a customer zone. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.GET, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + if (requestConfiguration != null) { + var requestConfig = new WithZoneItemRequestBuilderGetRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddQueryParameters(requestConfig.QueryParameters); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Replaces all records of the same name and type with the ones provided. + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPatchRequestInformation(List body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPatchRequestInformation(List body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.PATCH, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new WithZoneItemRequestBuilderPatchRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Replaces all records in the zone with the ones provided + /// + /// The request body + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToPutRequestInformation(List body, Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToPutRequestInformation(List body, Action requestConfiguration = default) { +#endif + _ = body ?? throw new ArgumentNullException(nameof(body)); + var requestInfo = new RequestInformation { + HttpMethod = Method.PUT, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.SetContentFromParsable(RequestAdapter, "application/json", body); + if (requestConfiguration != null) { + var requestConfig = new WithZoneItemRequestBuilderPutRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Returns a customer zone. + /// + public class WithZoneItemRequestBuilderGetQueryParameters { + /// The record names that should be included (same as name field of Record) +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? RecordName { get; set; } +#nullable restore +#else + public string RecordName { get; set; } +#endif + /// A comma-separated list of record types that should be included +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? RecordType { get; set; } +#nullable restore +#else + public string RecordType { get; set; } +#endif + /// The FQDN used to filter all the record names that end with it. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public string? Suffix { get; set; } +#nullable restore +#else + public string Suffix { get; set; } +#endif + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithZoneItemRequestBuilderGetRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// Request query parameters + public WithZoneItemRequestBuilderGetQueryParameters QueryParameters { get; set; } = new WithZoneItemRequestBuilderGetQueryParameters(); + /// + /// Instantiates a new WithZoneItemRequestBuilderGetRequestConfiguration and sets the default values. + /// + public WithZoneItemRequestBuilderGetRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithZoneItemRequestBuilderPatchRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithZoneItemRequestBuilderPatchRequestConfiguration and sets the default values. + /// + public WithZoneItemRequestBuilderPatchRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class WithZoneItemRequestBuilderPutRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new WithZoneItemRequestBuilderPutRequestConfiguration and sets the default values. + /// + public WithZoneItemRequestBuilderPutRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/V1/Zones/ZonesRequestBuilder.cs b/DDNSUpdater/APIs/Ionos/V1/Zones/ZonesRequestBuilder.cs new file mode 100644 index 0000000..24cab21 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/V1/Zones/ZonesRequestBuilder.cs @@ -0,0 +1,117 @@ +using DDNSUpdater.APIs.Ionos.ApiClient.Models; +using DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones.Item; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace DDNSUpdater.APIs.Ionos.ApiClient.V1.Zones { + /// + /// Builds and executes requests for operations under \v1\zones + /// + public class ZonesRequestBuilder { + /// Path parameters for the request + private Dictionary PathParameters { get; set; } + /// The request adapter to use to execute the requests. + private IRequestAdapter RequestAdapter { get; set; } + /// Url template to use to build the URL for the current request builder + private string UrlTemplate { get; set; } + /// Gets an item from the DDNSUpdater.APIs.Ionos.ApiClient.v1.zones.item collection + public WithZoneItemRequestBuilder this[string position] { get { + var urlTplParams = new Dictionary(PathParameters); + if (!string.IsNullOrWhiteSpace(position)) urlTplParams.Add("zoneId", position); + return new WithZoneItemRequestBuilder(urlTplParams, RequestAdapter); + } } + /// + /// Instantiates a new ZonesRequestBuilder and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public ZonesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) { + _ = pathParameters ?? throw new ArgumentNullException(nameof(pathParameters)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones"; + var urlTplParams = new Dictionary(pathParameters); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Instantiates a new ZonesRequestBuilder and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public ZonesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) { + if(string.IsNullOrEmpty(rawUrl)) throw new ArgumentNullException(nameof(rawUrl)); + _ = requestAdapter ?? throw new ArgumentNullException(nameof(requestAdapter)); + UrlTemplate = "{+baseurl}/v1/zones"; + var urlTplParams = new Dictionary(); + if (!string.IsNullOrWhiteSpace(rawUrl)) urlTplParams.Add("request-raw-url", rawUrl); + PathParameters = urlTplParams; + RequestAdapter = requestAdapter; + } + /// + /// Returns list of customer zones. + /// + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task?> GetAsync(Action? requestConfiguration = default, CancellationToken cancellationToken = default) { +#nullable restore +#else + public async Task> GetAsync(Action requestConfiguration = default, CancellationToken cancellationToken = default) { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> { + {"401", Error.CreateFromDiscriminatorValue}, + {"500", Error.CreateFromDiscriminatorValue}, + }; + var collectionResult = await RequestAdapter.SendCollectionAsync(requestInfo, Zone.CreateFromDiscriminatorValue, errorMapping, cancellationToken); + return collectionResult?.ToList(); + } + /// + /// Returns list of customer zones. + /// + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action? requestConfiguration = default) { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action requestConfiguration = default) { +#endif + var requestInfo = new RequestInformation { + HttpMethod = Method.GET, + UrlTemplate = UrlTemplate, + PathParameters = PathParameters, + }; + requestInfo.Headers.Add("Accept", "application/json"); + if (requestConfiguration != null) { + var requestConfig = new ZonesRequestBuilderGetRequestConfiguration(); + requestConfiguration.Invoke(requestConfig); + requestInfo.AddRequestOptions(requestConfig.Options); + requestInfo.AddHeaders(requestConfig.Headers); + } + return requestInfo; + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + public class ZonesRequestBuilderGetRequestConfiguration { + /// Request headers + public RequestHeaders Headers { get; set; } + /// Request options + public IList Options { get; set; } + /// + /// Instantiates a new zonesRequestBuilderGetRequestConfiguration and sets the default values. + /// + public ZonesRequestBuilderGetRequestConfiguration() { + Options = new List(); + Headers = new RequestHeaders(); + } + } + } +} diff --git a/DDNSUpdater/APIs/Ionos/dns.yml b/DDNSUpdater/APIs/Ionos/dns.yml new file mode 100644 index 0000000..7caddb8 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/dns.yml @@ -0,0 +1,1200 @@ +openapi: 3.0.2 +info: + title: 'DNS API' + version: "1.0.2" + description: | + # Working with the API + Every endpoint uses the `X-API-Key` header for authorization, to obtain the key please see the [Official Documentation](/docs/getstarted). + + Please note that any zone or record updates might conflict with active services. In such cases, the DNS records belonging to the conflicting services will be deactivated. + + # Support + Support questions may be posted in English: API Support. + + Please note that we offer support in the business Hours Mo-Fri 9:00-17:00 EET. +

+
+ Release notes +
    +
  • Version 1.0.0 Exposed CRUD operations for customer zone.
  • +
  • Version 1.0.1 Added response body for UPDATE and CREATE record operations.
  • +
  • Version 1.0.2 Added new supported record types.
  • +
+
+

+ + # Contact + API Support - Website +servers: + - url: https://api.hosting.ionos.com/dns + description: Production server + +# Basic authentication +components: + schemas: + recordTypes: + type: string + description: Holds supported dns record types. + enum: [A, AAAA, CNAME, MX, NS, SOA, SRV, TXT, CAA, TLSA, SMIMEA, SSHFP, DS, HTTPS, SVCB, + CERT, URI, RP, LOC, OPENPGPKEY] + zoneTypes: + type: string + description: Represents the possible zone types. + enum: [NATIVE, SLAVE] + error: + type: object + properties: + code: + type: string + description: The error code. + message: + type: string + description: The error message. + record: + type: object + properties: + name: + type: string + type: + $ref: "#/components/schemas/recordTypes" + content: + type: string + ttl: + type: integer + description: Time to live for the record, recommended 3600. + prio: + type: integer + disabled: + type: boolean + default: false + description: When is true, the record is not visible for lookup. + record-response: + type: object + properties: + id: + type: string + name: + type: string + rootName: + type: string + description: Root zone name. + type: + $ref: "#/components/schemas/recordTypes" + content: + type: string + changeDate: + type: string + description: The date of the last change formatted as yyyy-MM-dd'T'HH:mm:ss.SSS'Z' + ttl: + type: integer + description: Time to live for the record, recommended 3600. + prio: + type: integer + disabled: + type: boolean + default: false + description: When is true, the record is not visible for lookup. + record-update: + type: object + properties: + disabled: + type: boolean + default: false + description: When is true, the record is not visible for lookup. + content: + type: string + ttl: + type: integer + description: Time to live for the record, recommended 3600. + prio: + type: integer + errors: + type: array + items: + properties: + invalidFields: + type: array + items: + type: string + requiredFields: + type: array + items: + type: string + invalid: + type: array + items: + type: string + inputRecord: + $ref: "#/components/schemas/record" + errorRecord: + $ref: "#/components/schemas/record" + zone: + type: object + properties: + name: + type: string + description: The zone name. + id: + type: string + description: The zone id. + type: + $ref: "#/components/schemas/zoneTypes" + customer-zone: + type: object + properties: + id: + type: string + description: The zone id. + name: + type: string + description: The zone name + type: + $ref: "#/components/schemas/zoneTypes" + records: + type: array + items: + $ref: "#/components/schemas/record-response" + dyn-dns-request: + type: object + properties: + domains: + type: array + items: + type: string + description: The zone name. + description: + type: string + description: Dynamic Dns description. + required: + - domains + dynamic-dns: + type: object + properties: + bulkId: + type: string + description: DynDns configuration identifier. + updateUrl: + type: string + description: "Use the url with GET to update the ips of (sub)domains. Query parameters: ipv4, ipv6." + domains: + type: array + items: + type: string + description: The zone name. + description: + type: string + description: Dynamic Dns description. + examples: + record: + value: + { + "name": "example-zone.de", + "type": "A", + "content": "1.2.3.4", + "ttl": 3600, + "prio": 10, + "disabled": false + } + record-response: + value: + { + "id": "22af3414-abbe-9e11-5df5-66fbe8e334b4", + "name": "example-zone.de", + "rootName": "example-zone.de", + "type": "A", + "content": "1.2.3.4", + "changeDate": "2019-12-09T13:04:25.772Z", + "ttl": 3600, + "prio": 0, + "disabled": false + } + record-update: + value: + { + "disabled": false, + "content": "1.1.1.1", + "ttl": 3600, + "prio":0 + } + record-updated: + value: + { + "id": "22af3414-abbe-9e11-5df5-66fbe8e334b4", + "name": "example-zone.de", + "rootName": "example-zone.de", + "type": "A", + "content": "1.1.1.1", + "changeDate": "2022-23-03T13:04:25.772Z", + "ttl": 3600, + "prio": 0, + "disabled": false + } + record-not-normalized: + value: + { + "name": "example-zone.de", + "type": "caa", + "content": "0 issuewild \"“example.org\"", + "ttl": 3600, + "disabled": false + } + record-normalized: + value: + { + "name": "example-zone.de", + "type": "CAA", + "content": "0 issuewild \"example.org\"", + "ttl": 3600, + "disabled": false + } + unauthorized-error: + value: [ + { + "code": "UNAUTHORIZED", + "message": "The customer is not authorized to do this operation." + } + ] + bad-request-invalid-domain-name-error: + value: + - code: INVALID_DOMAIN_NAME + message: Domain is missing/invalid or its tld is not supported yet. + bad-request-invalid-data-error: + value: [ + { + "code": "INVALID_DATA", + "message": "The request body is invalid or not supported by the endpoint." + } + ] + bad-request-invalid-record-error: + value: [ + { + "code": "INVALID_RECORD", + "message": "Record is invalid.", + "parameters": { + "requiredFields": [ + "type" + ] + } + } + ] + record-not-found-error: + value: [ + { + "code": "RECORD_NOT_FOUND", + "message": "Record does not exist." + } + ] + dyndns-not-found-error: + value: + - code: DYN_DNS_NOT_FOUND + message: Dynamic dns not found. + forbidden-error: + value: + - code: FORBIDDEN_REQUEST + message: Request not allowed. + internal-server-error: + value: [ + { + "code": "INTERNAL_SERVER_ERROR" + } + ] + bad-request-error: + value: [ + { + "code": "INVALID_RECORD", + "message": "Record is invalid.", + "parameters": { + "errorRecord": { + "name": "example-zone.de", + "disabled": false, + "rootName": "example-zone.de", + "content": "1.2.3.4", + "ttl": 3600, + "prio": 0, + }, + "requiredFields": [ + "type" + ] + } + } + ] + zones: + value: [ + { + "id": "11af3414-ebba-11e9-8df5-66fbe8a334b4", + "name": "test.com", + "type": "NATIVE" + } + ] + customer-zone: + value: { + "id": "11af3414-ebba-11e9-8df5-66fbe8a334b4", + "name": "example-zone.de", + "type": "NATIVE", + "records": [ + { + "id": "22af3414-abbe-9e11-5df5-66fbe8e334b4", + "name": "example-zone.de", + "rootName": "example-zone.de", + "type": "A", + "content": "1.1.1.1", + "changeDate": "2019-12-09T13:04:25.772Z", + "ttl": 3600, + "prio": 0, + "disabled": false + } + ] + } + record-list: + value: [ + { + "name": "example-zone.de", + "type": "A", + "content": "1.2.3.4", + "ttl": 3600, + "prio": 0, + "disabled": false + } + ] + record-list-created: + value: [ + { + "id": "22af3414-abbe-9e11-5df5-66fbe8e334b4", + "name": "example-zone.de", + "rootName": "example-zone.de", + "type": "A", + "content": "1.2.3.4", + "changeDate": "2022-23-03T13:04:25.772Z", + "ttl": 3600, + "prio": 0, + "disabled": false + } + ] + dyn-dns-request: + value: + domains: ["example-zone.de", "www.example-zone.de"] + description: My DynamicDns + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-Key + +security: + - ApiKeyAuth: [] + +paths: + /v1/zones: + get: + operationId: getZones + tags: + - Zones + description: Returns list of customer zones. + responses: + '200': + description: Succesful response. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/zone" + } + examples: + Zones: + $ref: "#/components/examples/zones" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + /v1/zones/{zoneId}: + get: + operationId: getZone + tags: + - Zones + description: Returns a customer zone. + parameters: + - in: header + name: X-API-Key + schema: + type: string + required: true + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: query + name: suffix + schema: + type: string + required: false + description: The FQDN used to filter all the record names that end with it. + example: subhost.example.com + - in: query + name: recordName + schema: + type: string + required: false + description: The record names that should be included (same as name field of Record) + example: www.subdomain.example.com + - in: query + name: recordType + schema: + type: string + required: false + description: A comma-separated list of record types that should be included + example: A,AAAA + responses: + '200': + description: Succesful response. + content: + application/json: + schema: + $ref: "#/components/schemas/customer-zone" + examples: + 'Customer zone': + $ref: "#/components/examples/customer-zone" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + patch: + operationId: patchZone + tags: + - Zones + description: Replaces all records of the same name and type with the ones provided. + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: header + name: X-API-Key + schema: + type: string + required: true + requestBody: + description: records + required: true + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/record" + examples: + 'Record list': + $ref: "#/components/examples/record-list" + responses: + '200': + description: Succesful response. + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/errors" + } + examples: + 'Bad request': + $ref: "#/components/examples/bad-request-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + put: + operationId: updateZone + tags: + - Zones + description: Replaces all records in the zone with the ones provided + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: header + name: X-API-Key + schema: + type: string + required: true + requestBody: + description: records + required: true + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/record" + examples: + 'Record list': + $ref: "#/components/examples/record-list" + responses: + '200': + description: Succesful response. + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/errors" + } + examples: + Bad request: + $ref: "#/components/examples/bad-request-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + "/v1/zones/{zoneId}/records": + post: + operationId: createRecords + tags: + - Records + description: Creates records for a customer zone. + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: header + name: X-API-Key + schema: + type: string + required: true + requestBody: + required: true + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/record" + examples: + 'Record list': + $ref: "#/components/examples/record-list" + responses: + '201': + description: Records created. + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/record-response" + examples: + 'Successful response': + $ref: "#/components/examples/record-list-created" + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Bad request: + $ref: "#/components/examples/bad-request-error" + Invalid Domain Name: + $ref: "#/components/examples/bad-request-invalid-domain-name-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Internal Server Error: + $ref: "#/components/examples/internal-server-error" + /v1/zones/{zoneId}/records/{recordId}: + get: + operationId: getRecord + tags: + - Records + description: Returns the record from the customer zone with the mentioned id. + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: path + name: recordId + schema: + type: string + required: true + description: The id of the record. + - in: header + name: X-API-Key + schema: + type: string + required: true + responses: + '200': + description: Succesful response. + content: + application/json: + schema: + $ref: "#/components/schemas/record-response" + examples: + 'Record': + $ref: "#/components/examples/record-response" + '404': + description: Record not found. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/record-not-found-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + delete: + operationId: deleteRecord + tags: + - Records + description: Delete a record from the customer zone. + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: path + name: recordId + schema: + type: string + required: true + description: The id of the record. + - in: header + name: X-API-Key + schema: + type: string + required: true + responses: + '200': + description: Succesful response. + '404': + description: Record not found. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/record-not-found-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + put: + operationId: updateRecord + tags: + - Records + description: Update a record from the customer zone. + parameters: + - in: path + name: zoneId + schema: + type: string + required: true + description: The id of the customer zone. + - in: path + name: recordId + schema: + type: string + required: true + description: The id of the record. + - in: header + name: X-API-Key + schema: + type: string + required: true + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/record-update" + examples: + 'Record': + $ref: "#/components/examples/record-update" + responses: + '200': + description: Record updated. + content: + application/json: + schema: + $ref: "#/components/schemas/record-response" + examples: + 'Successful response': + $ref: "#/components/examples/record-updated" + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/errors" + } + examples: + Bad request: + $ref: "#/components/examples/bad-request-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '404': + description: Record not found. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/record-not-found-error" + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Internal Server Error: + $ref: "#/components/examples/internal-server-error" + "/v1/dyndns": + post: + operationId: activateDynDns + tags: + - Dynamic DNS + description: | + Activate Dynamic Dns for a bundle of (sub)domains. The url from response will be used to update the ips of the (sub)domains. + The following quota applies: 2 requests per minute per IP address. + parameters: + - in: header + name: X-API-Key + schema: + type: string + required: true + requestBody: + description: Dynamic Dns configuration. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/dyn-dns-request" + examples: + 'Enable Dynamic DNS': + $ref: "#/components/examples/dyn-dns-request" + responses: + '200': + description: Succesful response. + content: + application/json: + schema: + $ref: '#/components/schemas/dynamic-dns' + example: + bulkId: 22af3414-abbe-9e11-5df5-66fbe8e334b4 + updateUrl: "https://ipv4.api.hosting.ionos.com/dns/v1/dyndns?q=dGVzdC50ZXN0" + domains: [ + "example-zone.de", + "www.example-zone.de" + ] + description: "My DynamicDns" + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Invalid Request: + $ref: "#/components/examples/bad-request-invalid-data-error" + Invalid Domain Name: + $ref: "#/components/examples/bad-request-invalid-domain-name-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '429': + description: Rate limit excedeed. + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Internal Server Error: + $ref: "#/components/examples/internal-server-error" + delete: + operationId: disableDynDns + tags: + - Dynamic DNS + description: | + Disable Dynamic Dns. + The following quota applies: 2 requests per minute per IP address. + parameters: + - in: header + name: X-API-Key + schema: + type: string + required: true + responses: + '200': + description: Succesful response. + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '429': + description: Rate limit excedeed. + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Internal Server Error: + $ref: "#/components/examples/internal-server-error" + "/v1/dyndns/{bulkId}": + parameters: + - in: path + name: bulkId + schema: + type: string + required: true + description: Dynamic Dns configuration identifier. + - in: header + name: X-API-Key + schema: + type: string + required: true + put: + operationId: updateDynDns + tags: + - Dynamic DNS + description: | + Update Dynamic Dns for bulk id. + The following quota applies: 2 requests per minute per IP address. + requestBody: + description: Dynamic Dns configuration. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/dyn-dns-request" + examples: + 'Update Dynamic DNS': + $ref: "#/components/examples/dyn-dns-request" + responses: + '200': + description: Succesful response. + '400': + description: Bad request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Invalid Request: + $ref: "#/components/examples/bad-request-invalid-data-error" + Invalid Domain Name: + $ref: "#/components/examples/bad-request-invalid-domain-name-error" + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '403': + description: Forbidden request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Forbidden: + $ref: "#/components/examples/forbidden-error" + '404': + description: DynDns not found error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Not Found: + $ref: "#/components/examples/dyndns-not-found-error" + '429': + description: Rate limit excedeed. + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/internal-server-error" + delete: + operationId: deleteDynDns + tags: + - Dynamic DNS + description: | + Disable Dynamic Dns for bulk id. + The following quota applies: 2 requests per minute per IP address. + parameters: + - in: header + name: X-API-Key + schema: + type: string + format: uuid + required: true + responses: + '200': + description: Succesful response. + '401': + description: Unauthorized request. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Unauthorized: + $ref: "#/components/examples/unauthorized-error" + '429': + description: Rate limit excedeed. + '500': + description: Internal server error. + content: + application/json: + schema: + type: array + items: { + $ref: "#/components/schemas/error" + } + examples: + Internal Server Error: + $ref: "#/components/examples/internal-server-error" diff --git a/DDNSUpdater/APIs/Ionos/kiota-lock.json b/DDNSUpdater/APIs/Ionos/kiota-lock.json new file mode 100644 index 0000000..0a8b008 --- /dev/null +++ b/DDNSUpdater/APIs/Ionos/kiota-lock.json @@ -0,0 +1,29 @@ +{ + "descriptionHash": "9A16B89F524811904DA32D7B012B195937F8B243B3A466F6D6D8CCEAA2513B867643FB85327DB2AFFE886448B547E97877797F36A997FD7DD4C87331BDCDEDCC", + "descriptionLocation": "C:\\Users\\elias\\RiderProjects\\IonosDynamicDNSUpdater\\DDNSUpdater\\APIs\\Ionos\\dns.yml", + "lockFileVersion": "1.0.0", + "kiotaVersion": "1.0.1", + "clientClassName": "IonosAPIClient", + "clientNamespaceName": "DDNSUpdater.APIs.Ionos.ApiClient", + "language": "CSharp", + "usesBackingStore": false, + "includeAdditionalData": true, + "serializers": [ + "Microsoft.Kiota.Serialization.Json.JsonSerializationWriterFactory", + "Microsoft.Kiota.Serialization.Text.TextSerializationWriterFactory", + "Microsoft.Kiota.Serialization.Form.FormSerializationWriterFactory" + ], + "deserializers": [ + "Microsoft.Kiota.Serialization.Json.JsonParseNodeFactory", + "Microsoft.Kiota.Serialization.Text.TextParseNodeFactory", + "Microsoft.Kiota.Serialization.Form.FormParseNodeFactory" + ], + "structuredMimeTypes": [ + "application/json", + "text/plain", + "application/x-www-form-urlencoded" + ], + "includePatterns": [], + "excludePatterns": [], + "disabledValidationRules": [] +} \ No newline at end of file diff --git a/DDNSUpdater/Abstracts/ADDNSService.cs b/DDNSUpdater/Abstracts/ADDNSService.cs new file mode 100644 index 0000000..dc2e019 --- /dev/null +++ b/DDNSUpdater/Abstracts/ADDNSService.cs @@ -0,0 +1,9 @@ +namespace DDNSUpdater.Abstracts; + +public abstract class ADDNSService +{ + public abstract void Update(); + + // Rest of the class implementation + // ... +} \ No newline at end of file diff --git a/DDNSUpdater/DDNSUpdater.csproj b/DDNSUpdater/DDNSUpdater.csproj index 5a51d44..6b5d0f3 100644 --- a/DDNSUpdater/DDNSUpdater.csproj +++ b/DDNSUpdater/DDNSUpdater.csproj @@ -12,10 +12,16 @@ + - - + + + + + + + diff --git a/DDNSUpdater/Models/Domain.cs b/DDNSUpdater/Models/Domain.cs index 4561060..510f632 100644 --- a/DDNSUpdater/Models/Domain.cs +++ b/DDNSUpdater/Models/Domain.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + namespace DDNSUpdater.Models; public class Domain @@ -10,4 +12,10 @@ public class Domain public string DomainString { get; set; } public string Key { get; set; } +} + + +public class DomainGroup +{ + public List Domains { get; set; } } \ No newline at end of file diff --git a/DDNSUpdater/Program.cs b/DDNSUpdater/Program.cs index 1941b29..d583863 100644 --- a/DDNSUpdater/Program.cs +++ b/DDNSUpdater/Program.cs @@ -8,54 +8,51 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using RestSharp; +// A generic method to parse a string value into an enum of type T static T ParseEnum(string value) { return (T) Enum.Parse(typeof(T), value, true); } +// Build the configuration object by loading configuration settings from an appsettings.json file var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false); +// Read the log level from the environment variable LogLevel, or set it to LogLevel.Information if the variable is not set LogLevel loglevel; if (Environment.GetEnvironmentVariables()["LogLevel"] != null) loglevel = ParseEnum(Environment.GetEnvironmentVariables()["LogLevel"].ToString()); else loglevel = LogLevel.Information; - var configuration = builder.Build(); -/*var logConfig = new OptionsMonitor(); -logConfig.CurrentValue.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan; -logConfig.CurrentValue.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed;*/ - +// Set up the service collection to configure and register application services var serviceProvider = new ServiceCollection() .AddSingleton(configuration) .AddLogging(logging => { - + // Add a custom SpecterConsoleLogger to the logging pipeline with color mappings for different log levels logging.AddSpecterConsoleLogger(configuration => { - // Replace warning value from appsettings.json of "Cyan" configuration.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan; configuration.LogLevelToColorMap[LogLevel.Debug] = ConsoleColor.DarkYellow; - // Replace warning value from appsettings.json of "Red" configuration.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed; }); + // Set the minimum log level to the value of the loglevel variable logging.SetMinimumLevel(loglevel); }) .AddSingleton() .AddSingleton() .BuildServiceProvider(); - - - +// Retrieve the DDNSService and ITimerService from the service provider and start them var dataAccess = serviceProvider.GetService(); dataAccess.Start(); var timerService = serviceProvider.GetService(); timerService.Start(); +// Wait for a key press before exiting the program Console.ReadKey(); diff --git a/DDNSUpdater/Services/DDNSService.cs b/DDNSUpdater/Services/DDNSService.cs index 830e07d..d07cbfc 100644 --- a/DDNSUpdater/Services/DDNSService.cs +++ b/DDNSUpdater/Services/DDNSService.cs @@ -5,27 +5,38 @@ using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Mime; +using System.Security.Authentication; using System.Threading.Tasks; +using DDNSUpdater.Abstracts; +using DDNSUpdater.APIs.Ionos; +using DDNSUpdater.APIs.Ionos.ApiClient; +using DDNSUpdater.APIs.Ionos.ApiClient.Models; using DDNSUpdater.Interfaces; using DDNSUpdater.Logging; using DDNSUpdater.Models; using DDNSUpdater.Models.Requests; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Abstractions.Authentication; +using Microsoft.Kiota.Http.HttpClientLibrary; using Newtonsoft.Json; using RestSharp; using Spectre.Console; using Console = Spectre.Console.AnsiConsole; -using ContentType = RestSharp.Serializers.ContentType; +using ContentType = RestSharp.ContentType; +using DynamicDns = DDNSUpdater.Models.Requests.DynamicDns; +using Method = RestSharp.Method; namespace DDNSUpdater.Services; -public class DDNSService : IDDNSService +public class DDNSService : ADDNSService { private List? UpdateURLs { get; set; } public List Domains { get; set; } private readonly ILogger _logger; + private IonosAPIClient _client; public DDNSService(ILogger logger,IConfiguration configuration) { @@ -44,8 +55,12 @@ public class DDNSService : IDDNSService Domains.Add(new Domain(env[0], env[1])); } } - + var authProvider = new AnonymousAuthenticationProvider(); + var requestAdapter = new HttpClientRequestAdapter(authProvider); + _client = new IonosAPIClient(requestAdapter); + + } public async void Start() @@ -60,8 +75,10 @@ public class DDNSService : IDDNSService _logger.LogInformation($"Fetched {UpdateURLs.Count} UpdateURLs"); } - public async void Update() + public override async void Update() { + if(UpdateURLs != null && UpdateURLs.Count != 0) + foreach (var UpdateURL in UpdateURLs) { try @@ -73,9 +90,10 @@ public class DDNSService : IDDNSService request.AddParameter("text/plain", body, ParameterType.RequestBody); var response = await client.ExecuteAsync(request); + _logger.LogInformation("Requesting Update on Ionos."); } - catch (Exception e) + catch (ApiException e) { _logger.LogError(e.Message); throw; @@ -117,43 +135,37 @@ public class DDNSService : IDDNSService } - foreach (var domainList in domainDict) + foreach (var (key, value) in domainDict) { try { - var dyndns = new DynamicDns() + var request = new DynDnsRequest(); + request.Domains = value; + request.Description = "My DynamicDns"; + + var reply = await _client.V1.Dyndns.PostAsync(request, configuration => { - Domains = domainList.Value, - Description = "My DynamicDns" - }; - var content = JsonConvert.SerializeObject(dyndns); - var client = new RestClient("https://api.hosting.ionos.com/dns/v1"); - var request = new RestRequest("/dyndns", Method.Post); - - - request.AddHeader("X-API-Key", domainList.Key); - - request.AddStringBody(content, ContentType.Json); - - var response = client.ExecutePost(request); - - if (response.StatusCode == HttpStatusCode.Forbidden) - { - _logger.LogError($"Could not Fetch UpdateURL for {domainList.Key}"); - Environment.Exit(7); - } + configuration.Headers = new RequestHeaders() + { + { "X-API-Key", key } + }; + }); + updateURLs.Add(reply.UpdateUrl); - _logger.LogDebug(response.Data.UpdateUrl); - updateURLs.Add(response.Data.UpdateUrl); } - catch (Exception error) + catch (ApiException error) { - _logger.LogError(error.Message); + string message = error.Message; + _logger.LogError(message); return null; } + + } return updateURLs; } + + } diff --git a/DDNSUpdater/Services/TimerService.cs b/DDNSUpdater/Services/TimerService.cs index b4bf798..c4f2c9d 100644 --- a/DDNSUpdater/Services/TimerService.cs +++ b/DDNSUpdater/Services/TimerService.cs @@ -5,34 +5,44 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace DDNSUpdater.Services; - -public class TimerService : ITimerService +namespace DDNSUpdater.Services { - private Timer timer; - private readonly ILogger _logger; - private readonly IServiceScopeFactory _factory; - private readonly int intervalMinutes; - - public TimerService(ILogger logger,IServiceScopeFactory factory, IConfiguration configuration) + public class TimerService : ITimerService { - _logger = logger; - _factory = factory; - intervalMinutes = configuration.GetValue("TimerIntervalMinutes"); - timer = new Timer(TimerCallback, null, TimeSpan.Zero, TimeSpan.FromMinutes(intervalMinutes)); - } + private Timer timer; + private readonly ILogger _logger; + private readonly IServiceScopeFactory _factory; + private readonly int intervalMinutes; - private async void TimerCallback(Object o) - { - _logger.LogDebug("Timer callback executed at " + DateTime.Now); - await using var asyncScope = _factory.CreateAsyncScope(); - var ddnsService = asyncScope.ServiceProvider.GetRequiredService(); - - ddnsService.Update(); - } + public TimerService(ILogger logger, IServiceScopeFactory factory, IConfiguration configuration) + { + _logger = logger; + _factory = factory; - public void Start() - { - _logger.LogInformation("Timer service started."); + // Read the interval time for the timer from the appsettings.json file + intervalMinutes = configuration.GetValue("TimerIntervalMinutes"); + + // Create a new Timer object that executes the TimerCallback method at intervals specified by intervalMinutes + timer = new Timer(TimerCallback, null, TimeSpan.Zero, TimeSpan.FromMinutes(intervalMinutes)); + } + + // This method is called each time the timer ticks + private async void TimerCallback(object o) + { + _logger.LogDebug("Timer callback executed at " + DateTime.Now); + + // Create a new service scope using the IServiceScopeFactory + await using var asyncScope = _factory.CreateAsyncScope(); + + // Retrieve an instance of the DDNSService from the service scope and call its Update method to perform the DDNS update + var ddnsService = asyncScope.ServiceProvider.GetRequiredService(); + ddnsService.Update(); + } + + // This method is called after the timer is initialized + public void Start() + { + _logger.LogInformation("Timer service started."); + } } } \ No newline at end of file diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj new file mode 100644 index 0000000..995f21f --- /dev/null +++ b/Tests/Tests.csproj @@ -0,0 +1,21 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + + + + diff --git a/Tests/UnitTest1.cs b/Tests/UnitTest1.cs new file mode 100644 index 0000000..c0540ca --- /dev/null +++ b/Tests/UnitTest1.cs @@ -0,0 +1,15 @@ +namespace Tests; + +public class Tests +{ + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } +} \ No newline at end of file diff --git a/Tests/Usings.cs b/Tests/Usings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/Tests/Usings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file