├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── Docs ├── .gitbook │ └── assets │ │ └── icon-circle-cloud.png ├── README.md ├── SUMMARY.md ├── functions-and-methods │ ├── actions.md │ ├── datacenter.md │ ├── firewalls │ │ ├── README.md │ │ └── firewalls-actions.md │ ├── image.md │ ├── location.md │ ├── networks │ │ ├── README.md │ │ └── networks-actions.md │ ├── servers-types.md │ ├── servers.md │ ├── ssh-keys.md │ └── volumes │ │ ├── README.md │ │ └── volumes-actions.md └── overview │ ├── compatibility.md │ ├── installation.md │ └── need-help-or-have-questions.md ├── HetznerCloudApi.sln ├── HetznerCloudApi ├── Client │ ├── ActionClient.cs │ ├── DatacenterClient.cs │ ├── FirewallActionClient.cs │ ├── FirewallClient.cs │ ├── ImageClient.cs │ ├── LocationClient.cs │ ├── NetworkActionClient.cs │ ├── NetworkClient.cs │ ├── ServerClient.cs │ ├── ServerTypeClient.cs │ ├── SshKeyClient.cs │ ├── VolumeActionClient.cs │ └── VolumeClient.cs ├── Core.cs ├── HetznerCloudApi.csproj ├── HetznerCloudClient.cs ├── Object │ ├── Action │ │ ├── Action.cs │ │ └── Get │ │ │ └── Response.cs │ ├── Datacenter │ │ ├── Datacenter.cs │ │ └── Get │ │ │ └── Response.cs │ ├── Firewall │ │ ├── Firewall.cs │ │ └── Get │ │ │ └── Response.cs │ ├── Image │ │ ├── Get │ │ │ └── Response.cs │ │ └── Image.cs │ ├── Location │ │ ├── Get │ │ │ └── Response.cs │ │ └── Location.cs │ ├── Network │ │ ├── Get │ │ │ └── Response.cs │ │ └── Network.cs │ ├── PlacementGroup │ │ └── PlacementGroup.cs │ ├── Server │ │ ├── Get │ │ │ └── Response.cs │ │ └── Server.cs │ ├── ServerType │ │ ├── Get │ │ │ └── Response.cs │ │ └── ServerType.cs │ ├── SshKey │ │ ├── Get │ │ │ └── Response.cs │ │ └── SshKey.cs │ ├── Universal │ │ ├── Enum.cs │ │ ├── Error.cs │ │ ├── Meta.cs │ │ └── Protection.cs │ └── Volume │ │ ├── Get │ │ └── Response.cs │ │ └── Volume.cs └── icon-circle-cloud.png ├── LICENSE ├── README.md ├── Test ├── Program.cs └── Test.csproj └── icon_128.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Version 0.1.2 (2023-11-22) 4 | - Server; Complete 5 | 6 | ## Version 0.1.1 (2023-11-13) 7 | - Networks Actions; Complete 8 | 9 | ## Version 0.1.0 (2023-11-12) 10 | - Netowkrs; Complete 11 | 12 | ## Version 0.0.9 (2023-11-05) 13 | - Firewall Actions; Complete 14 | 15 | ## Version 0.0.8 (2023-11-05) 16 | - Firewalls; Complete 17 | 18 | ## Version 0.0.7 (2023-11-04) 19 | - SSH Keys; Complete 20 | 21 | ## Version 0.0.6 (2023-11-02) 22 | - Actions; Complete 23 | 24 | ## Version 0.0.5 (2023-11-02) 25 | - Global; The object properties have been changed to avoid conflicts with null values. This is done for compatibility with .NET Framework (This change is transparent to the user) 26 | - Volume; Complete 27 | - Volume Actions; Complete 28 | 29 | ## Version 0.0.4 (2023-11-02) 30 | - Datacenters; Complete 31 | - Locations; Corrected the name of the internal variable in Locations 32 | 33 | ## Version 0.0.3 (2023-11-02) 34 | - Locations; Complete 35 | 36 | ## Version 0.0.2 (2023-11-01) 37 | - ServerType; Complete 38 | - When searching for an object and if it doesn't exist, it used to throw an exception. It has been changed to return an empty object instead of an exception 39 | 40 | ## Version 0.0.1 (2023-10-31) 41 | - Image; Complete 42 | - Project initiation 43 | - Add logo 44 | - Add readme 45 | - Add changelog -------------------------------------------------------------------------------- /Docs/.gitbook/assets/icon-circle-cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljchuello/HetznerCloud.API/64f7eaaf3070dface8fb24f3bd2b10964da76b75/Docs/.gitbook/assets/icon-circle-cloud.png -------------------------------------------------------------------------------- /Docs/README.md: -------------------------------------------------------------------------------- 1 | # 🌐 Hetzner Cloud API 2 | 3 |
4 | 5 |
Hetzner
6 | 7 |
8 | 9 | This project is your complete guide to exploring and utilizing the Hetzner Cloud API. Here, you'll find everything you need to integrate your projects with one of the most powerful and efficient cloud platforms. 10 | 11 | **Key Features:** 12 | 13 | * **Quick Start:** Begin with simple examples to connect and use the API. 🖥️ 14 | * **Detailed API Reference:** Each endpoint is explained with code examples, making it easy even for beginners. 📚 15 | * **Use Cases:** Discover how other developers are leveraging the API in real-world scenarios. 💡 16 | * **Security and Best Practices:** Learn to use the API securely and efficiently. 🔐 17 | * **Support and Community:** Join our community and get help when you need it. 👥 18 | 19 | **Who is This Book For?** 20 | 21 | * **System and Web Developers:** If you program in C#, Angular, or any other language, you'll find useful resources here. 22 | * **IT and Network Professionals:** Tips for securing and optimizing your cloud projects. 23 | 24 | **Start Now!** Navigate the chapters, dive into the example codes, and take your cloud projects to the next level. We're here to help you every step of the way! 🌟Installation 25 | 26 | To install you must go to Nuget package manager and search for **HetznerCloud.API** and then install. 27 | 28 | [**NuGet Package**](https://www.nuget.org/packages/HetznerCloud.API/) 29 | 30 | ```powershell 31 | PM> dotnet add package HetznerCloud.API 32 | ``` 33 | 34 | *** 35 | 36 | ## :heavy\_check\_mark: Implemented functionality 37 | 38 | :heavy\_check\_mark: - Available on API, implemented\ 39 | :x: - Available on API, not implemented\ 40 | :heavy\_minus\_sign: - Not available on API 41 | 42 |
Get allGet oneCreateUpdateDeleteActions
Actions
Datacenters
Firewalls
Firewalls Actions
Images
Locations
Networks
Networks Actions
Servers
Server Types
SSH Keys
Volumes
Volumes Actions
43 | 44 | -------------------------------------------------------------------------------- /Docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | ## Overview 4 | 5 | * [🌐 Hetzner Cloud API](README.md) 6 | * [🔗 Compatibility](overview/compatibility.md) 7 | * [🔧 Installation](overview/installation.md) 8 | * [🆘 Need help or have questions?](overview/need-help-or-have-questions.md) 9 | 10 | ## Functions & Methods 11 | 12 | * [⏰ Actions](functions-and-methods/actions.md) 13 | * [🌎 Datacenter](functions-and-methods/datacenter.md) 14 | * [🚧 Firewalls](functions-and-methods/firewalls/README.md) 15 | * [Firewalls Actions](functions-and-methods/firewalls/firewalls-actions.md) 16 | * [📸 Image](functions-and-methods/image.md) 17 | * [🗺️ Location](functions-and-methods/location.md) 18 | * [🌐 Networks](functions-and-methods/networks/README.md) 19 | * [Networks Actions](functions-and-methods/networks/networks-actions.md) 20 | * [🖥️ Servers](functions-and-methods/servers.md) 21 | * [🗄️ Servers Types](functions-and-methods/servers-types.md) 22 | * [🔐 SSH Keys](functions-and-methods/ssh-keys.md) 23 | * [📦 Volumes](functions-and-methods/volumes/README.md) 24 | * [Volumes Actions](functions-and-methods/volumes/volumes-actions.md) 25 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/actions.md: -------------------------------------------------------------------------------- 1 | # ⏰ Actions 2 | 3 | ## Get all Actions 4 | 5 | Returns all Action objects. 6 | 7 | ```csharp 8 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 9 | 10 | List list = await hetznerCloudClient.Action.Get(); 11 | ``` 12 | 13 | ## Get an Action 14 | 15 | Returns a specific Action. 16 | 17 | ```csharp 18 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 19 | 20 | long actionId = 1236866267; 21 | 22 | Action action = await hetznerCloudClient.Action.Get(actionId); 23 | ``` 24 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/datacenter.md: -------------------------------------------------------------------------------- 1 | # 🌎 Datacenter 2 | 3 | Each Datacenter represents a virtual Datacenter which is made up of possible many physical Datacenters where Servers are hosted. 4 | 5 | ## Get all Datacenters 6 | 7 | Returns all Datacenter objects. 8 | 9 | ```csharp 10 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 11 | 12 | // Get All 13 | List listDatacenters = await hetznerCloudClient.Datacenter.Get(); 14 | ``` 15 | 16 | ## Get a Datacenter 17 | 18 | Returns a specific Datacenter object. 19 | 20 | ```csharp 21 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 22 | 23 | // Set ID 24 | long DatacenterId = 3; 25 | 26 | // Get 27 | Datacenter datacenter = await hetznerCloudClient.Datacenter.Get(DatacenterId); 28 | ``` 29 | 30 | ## eDataCenter 31 | 32 | The `eDataCenter` enum has also been created for the purpose of standardizing resource creation 33 | 34 | | Datacenter ID | Location ID | Name | Ciudad | Network Zone | 35 | | ------------- | ----------- | ---- | ------------- | ------------ | 36 | | 4 | 1 | fsn1 | Falkenstein | eu-central | 37 | | 2 | 2 | nbg1 | Nuremberg | eu-central | 38 | | 3 | 3 | hel1 | Helsinki | eu-central | 39 | | 5 | 4 | ash | Ashburn, VA | us-east | 40 | | 6 | 5 | hil | Hillsboro, OR | us-west | 41 | 42 | ## **JSON** 43 | 44 | ```json 45 | { 46 | "datacenter": { 47 | "description": "Helsinki 1 virtual DC 2", 48 | "id": 3, 49 | "location": { 50 | "city": "Helsinki", 51 | "country": "FI", 52 | "description": "Helsinki DC Park 1", 53 | "id": 3, 54 | "latitude": 60.169855, 55 | "longitude": 24.938379, 56 | "name": "hel1", 57 | "network_zone": "eu-central" 58 | }, 59 | "name": "hel1-dc2", 60 | "server_types": { 61 | "available": [ 62 | 1, 63 | 3, 64 | 5, 65 | 7, 66 | 9, 67 | 22, 68 | 23, 69 | 24, 70 | 25, 71 | 26, 72 | 45, 73 | 93, 74 | 94, 75 | 95, 76 | 96, 77 | 97, 78 | 98, 79 | 99, 80 | 100, 81 | 101 82 | ], 83 | "available_for_migration": [ 84 | 1, 85 | 3, 86 | 5, 87 | 7, 88 | 9, 89 | 22, 90 | 23, 91 | 24, 92 | 25, 93 | 26, 94 | 45, 95 | 93, 96 | 94, 97 | 95, 98 | 96, 99 | 97, 100 | 98, 101 | 99, 102 | 100, 103 | 101 104 | ], 105 | "supported": [ 106 | 9, 107 | 7, 108 | 5, 109 | 3, 110 | 1, 111 | 22, 112 | 23, 113 | 24, 114 | 25, 115 | 26, 116 | 45, 117 | 93, 118 | 94, 119 | 95, 120 | 96, 121 | 97, 122 | 98, 123 | 99, 124 | 100, 125 | 101 126 | ] 127 | } 128 | } 129 | } 130 | ``` 131 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/firewalls/README.md: -------------------------------------------------------------------------------- 1 | # 🚧 Firewalls 2 | 3 | Firewalls can limit the network access to or from your resources. 4 | 5 | * When applying a firewall with no in rule all inbound traffic will be dropped. The default for in is DROP. 6 | * When applying a firewall with no out rule all outbound traffic will be accepted. The default for out is ACCEPT. 7 | 8 | ## Get all Firewalls 9 | 10 | Returns all Firewall objects. 11 | 12 | ```csharp 13 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 14 | 15 | List list = await hetznerCloudClient.Firewall.Get(); 16 | ``` 17 | 18 | ## Get a Firewall 19 | 20 | Gets a specific Firewall object. 21 | 22 | ```csharp 23 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 24 | 25 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 26 | ``` 27 | 28 | ## Create a Firewall 29 | 30 | Creates a new Firewall. 31 | 32 | Once created, you can start managing the rules in the 'Firewall Actions' section. 33 | 34 | ```csharp 35 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 36 | 37 | // Create 38 | Firewall firewall = await hetznerCloudClient.Firewall.Create("firewall example"); 39 | ``` 40 | 41 | ## Update a Firewall 42 | 43 | Updates the Firewall. 44 | 45 | ```csharp 46 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 47 | 48 | // Get 49 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 50 | 51 | // Change 52 | firewall.Name = "cyberpanel"; 53 | 54 | // Update 55 | firewall = await hetznerCloudClient.Firewall.Update(firewall); 56 | ``` 57 | 58 | ## Delete a Firewall 59 | 60 | Deletes a Firewall. 61 | 62 | ```csharp 63 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 64 | 65 | // Get 66 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 67 | 68 | // You can delete it by passing the Firewall as a parameter 69 | await hetznerCloudClient.Firewall.Delete(firewall); 70 | 71 | // You can also delete it by passing the Firewall ID as a parameter. 72 | await hetznerCloudClient.Firewall.Delete(1012861); 73 | ``` 74 | 75 | ## **JSON** 76 | 77 | ```json 78 | { 79 | "firewall": { 80 | "id": 1112794, 81 | "name": "firewall-example", 82 | "labels": {}, 83 | "created": "2023-11-05T19:40:21.506374+00:00", 84 | "rules": [ 85 | { 86 | "direction": "in", 87 | "protocol": "tcp", 88 | "port": "80", 89 | "source_ips": [ 90 | "0.0.0.0/0", 91 | "::/0" 92 | ], 93 | "destination_ips": [], 94 | "description": null 95 | }, 96 | { 97 | "direction": "in", 98 | "protocol": "tcp", 99 | "port": "443", 100 | "source_ips": [ 101 | "0.0.0.0/0", 102 | "::/0" 103 | ], 104 | "destination_ips": [], 105 | "description": null 106 | }, 107 | { 108 | "direction": "in", 109 | "protocol": "tcp", 110 | "port": "15-20", 111 | "source_ips": [ 112 | "0.0.0.0/0", 113 | "::/0" 114 | ], 115 | "destination_ips": [], 116 | "description": null 117 | }, 118 | { 119 | "direction": "out", 120 | "protocol": "tcp", 121 | "port": "any", 122 | "source_ips": [], 123 | "destination_ips": [ 124 | "0.0.0.0/0", 125 | "::/0" 126 | ], 127 | "description": null 128 | } 129 | ], 130 | "applied_to": [ 131 | { 132 | "type": "server", 133 | "server": { 134 | "id": 38976603 135 | } 136 | } 137 | ] 138 | } 139 | } 140 | ``` 141 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/firewalls/firewalls-actions.md: -------------------------------------------------------------------------------- 1 | # Firewalls Actions 2 | 3 | Firewalls can limit the network access to or from your resources. 4 | 5 | * When applying a firewall with no in rule all inbound traffic will be dropped. The default for in is DROP. 6 | * When applying a firewall with no out rule all outbound traffic will be accepted. The default for out is ACCEPT. 7 | 8 | ## Apply to Resources 9 | 10 | Applies one Firewall to multiple resources. 11 | 12 | ```csharp 13 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 14 | 15 | // Get 16 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 17 | 18 | long serverId = 38976603; 19 | 20 | // Apply to resources 21 | List listAcionAction = await hetznerCloudClient.FirewallAction.ApplyToResources(firewall.Id, serverId); 22 | ``` 23 | 24 | ## Remove from Resources 25 | 26 | Removes one Firewall from multiple resources. 27 | 28 | ```csharp 29 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 30 | 31 | // Get 32 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 33 | 34 | long serverId = 38976603; 35 | 36 | // Remove from Resources 37 | List listAcionAction = await hetznerCloudClient.FirewallAction.RemoveFromResources(firewall.Id, serverId); 38 | ``` 39 | 40 | ## Set Rules 41 | 42 | Sets the rules of a Firewall. 43 | 44 | To establish the rules it is important to take into account that; 45 | 46 | 1. Rules are not removed, they are replaced 47 | 2. The rules cannot be obtained directly, the rules are obtained from the Rules property of the Firewall object 48 | 3. If there are no ingress rules, it will allow all incoming traffic 49 | 4. If there are no outbound rules, it will allow all outbound traffic 50 | 51 | For the first example we are going to allow access to ports 80 and 22 52 | 53 | ```csharp 54 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 55 | 56 | // Get the object 57 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 58 | 59 | // List rules 60 | List listRules = new List(); 61 | 62 | // Enable port 80 / tcp / in / All traffic ipv4 and ipv6 63 | listRules.Add(new Rule 64 | { 65 | Direction = Direction.@in, 66 | Protocol = Protocol.tcp, 67 | Port = "80", 68 | Description = "Port 80 for http", 69 | SourceIps = new List { "0.0.0.0/0", "::/0" } 70 | }); 71 | 72 | // Enable port 22 / tcp / in / All traffic ipv4 and ipv6 73 | listRules.Add(new Rule 74 | { 75 | Direction = Direction.@in, 76 | Protocol = Protocol.tcp, 77 | Port = "22", 78 | Description = "Port 22 for https", 79 | SourceIps = new List { "0.0.0.0/0", "::/0" } 80 | }); 81 | 82 | // Send rules 83 | List listAction = await hetznerCloudClient.FirewallAction.SetRulesTask(firewall, listRules); 84 | ``` 85 | 86 | Now, we are going to allow all outgoing traffic (although it is redundant because not specifying this will allow all traffic) 87 | 88 | Notice how we use `List listRules = firewall.Rules;` this is to keep the current rules and add a new one. If we don't do this, we would be replacing the existing rules with the new ones. 89 | 90 | In other words, if we don't do this, the new rules will replace the old ones, and the old ones will be deleted. 91 | 92 | ```csharp 93 | // Get the object 94 | Firewall firewall = await hetznerCloudClient.Firewall.Get(1012861); 95 | 96 | // Get pre-existing rules 97 | List listRules = firewall.Rules; 98 | 99 | //Add new rule 100 | listRules.Add(new Rule() 101 | { 102 | Direction = Direction.@out, 103 | Protocol = Protocol.tcp, 104 | Port = "any", 105 | Description = "All port out open", 106 | DestinationIps = new List { "0.0.0.0/0", "::/0" } 107 | }); 108 | 109 | // Set rules 110 | List listAction = await hetznerCloudClient.FirewallAction.SetRules(firewall, listRules); 111 | ``` 112 | 113 | ## Get all Actions for a Firewall 114 | 115 | Returns all Action objects for a Firewall. 116 | 117 | ```csharp 118 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 119 | 120 | long firewallId = 1012861; 121 | 122 | List list = await hetznerCloudClient.FirewallAction.GetAllActions(firewallId); 123 | ``` 124 | 125 | ## Get an Action for a Firewall 126 | 127 | Returns a specific Action for a Firewall. 128 | 129 | ```csharp 130 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 131 | 132 | long firewallId = 1012861; 133 | long actionId = 1124587761; 134 | 135 | Action action = await hetznerCloudClient.FirewallAction.GetAction(firewallId, actionId); 136 | ``` 137 | 138 | ## Get all Actions 139 | 140 | Returns all Action objects. 141 | 142 | ```csharp 143 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 144 | 145 | List list = await hetznerCloudClient.FirewallAction.GetAllActions(); 146 | ``` 147 | 148 | ## Get an Action 149 | 150 | Returns a specific Action. 151 | 152 | ```csharp 153 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 154 | 155 | long actionId = 1124587761; 156 | 157 | Action action = await hetznerCloudClient.FirewallAction.GetAction(actionId); 158 | ``` 159 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/image.md: -------------------------------------------------------------------------------- 1 | # 📸 Image 2 | 3 | The images are blueprints for your VM disks. They can be of different types: system images, snapshot images, or backup images. 4 | 5 | ## Get all Images 6 | 7 | Returns all Image objects. 8 | 9 | ```csharp 10 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 11 | 12 | List listImage = await hetznerCloudClient.Image.Get(); 13 | ``` 14 | 15 | ## Get an Image 16 | 17 | Returns a specific Image object. 18 | 19 | ```csharp 20 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 21 | 22 | Image image = await hetznerCloudClient.Image.Get(123); 23 | ``` 24 | 25 | ## **JSON** 26 | 27 | ```json 28 | { 29 | "image": { 30 | "id": 45557056, 31 | "type": "system", 32 | "status": "available", 33 | "name": "debian-11", 34 | "description": "Debian 11", 35 | "image_size": null, 36 | "disk_size": 5, 37 | "created": "2021-08-16T11:12:01+00:00", 38 | "created_from": null, 39 | "bound_to": null, 40 | "os_flavor": "debian", 41 | "os_version": "11", 42 | "rapid_deploy": true, 43 | "protection": { 44 | "delete": false 45 | }, 46 | "deprecated": null, 47 | "labels": {}, 48 | "deleted": null, 49 | "architecture": "x86" 50 | } 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/location.md: -------------------------------------------------------------------------------- 1 | # 🗺️ Location 2 | 3 | Datacenters are organized by Locations. Datacenters in the same Location are connected with very low latency links. 4 | 5 | ## Get all Locations 6 | 7 | Returns all Location objects. 8 | 9 | ```csharp 10 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 11 | 12 | // Get All 13 | List listLocation = await hetznerCloudClient.Location.Get(); 14 | ``` 15 | 16 | ## Get a Location 17 | 18 | Returns a specific Location object. 19 | 20 | ```csharp 21 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 22 | 23 | // Set ID 24 | long LocationId = 2; 25 | 26 | // Get 27 | Location location = await hetznerCloudClient.Location.Get(LocationId); 28 | ``` 29 | 30 | ## eDataCenter 31 | 32 | The `eDataCenter` enum has also been created for the purpose of standardizing resource creation 33 | 34 | | Datacenter ID | Location ID | Name | Ciudad | Network Zone | 35 | | ------------- | ----------- | ---- | ------------- | ------------ | 36 | | 4 | 1 | fsn1 | Falkenstein | eu-central | 37 | | 2 | 2 | nbg1 | Nuremberg | eu-central | 38 | | 3 | 3 | hel1 | Helsinki | eu-central | 39 | | 5 | 4 | ash | Ashburn, VA | us-east | 40 | | 6 | 5 | hil | Hillsboro, OR | us-west | 41 | 42 | ## **JSON** 43 | 44 | ```json 45 | { 46 | "location": { 47 | "city": "Nuremberg", 48 | "country": "DE", 49 | "description": "Nuremberg DC Park 1", 50 | "id": 2, 51 | "latitude": 49.452102, 52 | "longitude": 11.076665, 53 | "name": "nbg1", 54 | "network_zone": "eu-central" 55 | } 56 | } 57 | ``` 58 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/networks/README.md: -------------------------------------------------------------------------------- 1 | # 🌐 Networks 2 | 3 | Networks is a private networks feature. These Networks are optional and they coexist with the public network that every Server has by default. 4 | 5 | They allow Servers to talk to each other over a dedicated network interface using private IP addresses not available publicly. 6 | 7 | The IP addresses are allocated and managed via the API, they must conform to [RFC1918](https://tools.ietf.org/html/rfc1918#section-3) standard. IPs and network interfaces defined under Networks do not provide public internet connectivity, you will need to use the already existing public network interface for that. 8 | 9 | Each network has a user selected `ip_range` which defines all available IP addresses which can be used for Subnets within the Network. 10 | 11 | To assign individual IPs to Servers you will need to create Network Subnets, described below. 12 | 13 | Currently Networks support IPv4 only. 14 | 15 | ## Get all Networks 16 | 17 | Gets all existing networks that you have available. 18 | 19 | ```csharp 20 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 21 | 22 | List list = await hetznerCloudClient.Network.Get(); 23 | ``` 24 | 25 | ## Get a Network 26 | 27 | Gets a specific network object. 28 | 29 | ```csharp 30 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 31 | 32 | long networkId = 3545643; 33 | 34 | Network network = await hetznerCloudClient.Network.Get(networkId); 35 | ``` 36 | 37 | ## Create a Network 38 | 39 | Creates a network with the specified ip\_range. 40 | 41 | ```csharp 42 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 43 | 44 | Network network = await hetznerCloudClient.Network.Create("network-name", "192.168.0.0/16"); 45 | ``` 46 | 47 | ## Update a Network 48 | 49 | Updates the network properties. 50 | 51 | ```csharp 52 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 53 | 54 | // Get one 55 | Network network = await hetznerCloudClient.Network.Get(3550103); 56 | 57 | // Edit name 58 | network.Name = $"new-name"; 59 | 60 | // Update 61 | network = await hetznerCloudClient.Network.Update(network); 62 | ``` 63 | 64 | ## Delete a Network 65 | 66 | Deletes a network. If there are Servers attached they will be detached in the background. 67 | 68 | ```csharp 69 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 70 | 71 | // Get one 72 | Network network = await hetznerCloudClient.Network.Get(3550103); 73 | 74 | // You can delete it by passing the object as a parameter 75 | await hetznerCloudClient.Network.Delete(network); 76 | 77 | // You can also delete it by passing the ID as a parameter. 78 | await hetznerCloudClient.Network.Delete(3550103); 79 | ``` 80 | 81 | ## **JSON** 82 | 83 | ```json 84 | { 85 | "network": { 86 | "id": 3550135, 87 | "name": "network", 88 | "ip_range": "192.168.0.0/16", 89 | "subnets": [ 90 | { 91 | "type": "cloud", 92 | "ip_range": "192.168.0.0/20", 93 | "network_zone": "eu-central", 94 | "vswitch_id": null, 95 | "gateway": "192.168.0.1" 96 | }, 97 | { 98 | "type": "cloud", 99 | "ip_range": "192.168.16.0/20", 100 | "network_zone": "eu-central", 101 | "vswitch_id": null, 102 | "gateway": "192.168.0.1" 103 | } 104 | ], 105 | "routes": [ 106 | { 107 | "destination": "192.168.32.0/24", 108 | "gateway": "192.168.16.1" 109 | } 110 | ], 111 | "servers": [ 112 | 39271989 113 | ], 114 | "load_balancers": [ 115 | 1535492 116 | ], 117 | "protection": { 118 | "delete": false 119 | }, 120 | "labels": {}, 121 | "created": "2023-11-12T16:25:32+00:00", 122 | "expose_routes_to_vswitch": false 123 | } 124 | } 125 | ``` 126 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/networks/networks-actions.md: -------------------------------------------------------------------------------- 1 | # Networks Actions 2 | 3 | ## Add a subnet to a Network 4 | 5 | Adds a new subnet object to the Network. If you do not specify an ip\_range for the subnet we will automatically pick the first available /24 range for you if possible. 6 | 7 | ```csharp 8 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 9 | 10 | long networkId = 3553797; 11 | string ipRange = "192.168.32.0/20"; 12 | string networkZone = "eu-central"; 13 | 14 | Action action = await hetznerCloudClient.NetworkAction.AddSubnetToNetwork(networkId, ipRange, networkZone); 15 | ``` 16 | 17 | ## Delete a subnet from a Network 18 | 19 | Deletes a single subnet entry from a Network. You cannot delete subnets which still have Servers attached. If you have Servers attached you first need to detach all Servers that use IPs from this subnet before you can delete the subnet. 20 | 21 | ```csharp 22 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 23 | 24 | long networkId = 3553797; 25 | string ipRange = "192.168.32.0/20"; 26 | 27 | Action action = await hetznerCloudClient.NetworkAction.DeleteSubnetFromNetwork(networkId, ipRange); 28 | ``` 29 | 30 | ## Change NetworkProtection 31 | 32 | Changes the protection configuration of a Network. 33 | 34 | ```csharp 35 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 36 | 37 | long networkId = 2446116; 38 | bool protection = true; // True => Enable protection | False => Disable protection 39 | Action action = await hetznerCloudClient.NetworkAction.ChangeProtection(networkId, protection); 40 | ``` 41 | 42 | ## Get all Actions for a Network 43 | 44 | Returns all Action objects for a Network. 45 | 46 | ```csharp 47 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 48 | 49 | long networkId = 100051962; 50 | 51 | List list = await hetznerCloudClient.NetworkAction.GetAllActions(networkId); 52 | ``` 53 | 54 | ## Get an Action for a Network 55 | 56 | Returns a specific Action for a Network. 57 | 58 | ```csharp 59 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 60 | 61 | long networkId = 100051962; 62 | long actionId = 1236866267; 63 | 64 | Action action = await hetznerCloudClient.NetworkAction.GetAction(networkId, actionId); 65 | ``` 66 | 67 | ## Get all Actions 68 | 69 | Returns all Action objects. 70 | 71 | ```csharp 72 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 73 | 74 | List list = await hetznerCloudClient.NetworkAction.GetAllActions(); 75 | ``` 76 | 77 | ## Get an Action 78 | 79 | Returns a specific Action. 80 | 81 | ```csharp 82 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 83 | 84 | long actionId = 1236866267; 85 | 86 | Action action = await hetznerCloudClient.NetworkAction.GetAction(actionId); 87 | ``` 88 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/servers-types.md: -------------------------------------------------------------------------------- 1 | # 🗄️ Servers Types 2 | 3 | Server types define kinds of Servers offered. Each type has an hourly and a monthly cost. You will pay whichever cost is lower for your usage of this specific Server. Costs may differ between Locations. 4 | 5 | Currency for all amounts is €. All prices exclude VAT. 6 | 7 | ## Get all Server Types 8 | 9 | Gets all Server type objects. 10 | 11 | ```csharp 12 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 13 | 14 | // Get All 15 | List listServerTypes = await hetznerCloudClient.ServerType.Get(); 16 | ``` 17 | 18 | ## Get a Server Type 19 | 20 | Gets a specific Server type object. 21 | 22 | ```csharp 23 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 24 | 25 | // Set ID 26 | long serverTypeId = 15, 27 | 28 | // Get 29 | ServerType serverType = await hetznerCloudClient.ServerType.Get(serverTypeId); 30 | ``` 31 | 32 | ## **JSON** 33 | 34 | ```json 35 | { 36 | "server_type": { 37 | "id": 22, 38 | "name": "cpx11", 39 | "description": "CPX 11", 40 | "cores": 2, 41 | "memory": 2.0, 42 | "disk": 40, 43 | "deprecated": false, 44 | "prices": [ 45 | { 46 | "location": "ash", 47 | "price_hourly": { 48 | "net": "0.0063000000", 49 | "gross": "0.0063000000000000" 50 | }, 51 | "price_monthly": { 52 | "net": "3.8500000000", 53 | "gross": "3.8500000000000000" 54 | } 55 | }, 56 | { 57 | "location": "hel1", 58 | "price_hourly": { 59 | "net": "0.0063000000", 60 | "gross": "0.0063000000000000" 61 | }, 62 | "price_monthly": { 63 | "net": "3.8500000000", 64 | "gross": "3.8500000000000000" 65 | } 66 | }, 67 | { 68 | "location": "nbg1", 69 | "price_hourly": { 70 | "net": "0.0063000000", 71 | "gross": "0.0063000000000000" 72 | }, 73 | "price_monthly": { 74 | "net": "3.8500000000", 75 | "gross": "3.8500000000000000" 76 | } 77 | }, 78 | { 79 | "location": "hil", 80 | "price_hourly": { 81 | "net": "0.0063000000", 82 | "gross": "0.0063000000000000" 83 | }, 84 | "price_monthly": { 85 | "net": "3.8500000000", 86 | "gross": "3.8500000000000000" 87 | } 88 | }, 89 | { 90 | "location": "fsn1", 91 | "price_hourly": { 92 | "net": "0.0063000000", 93 | "gross": "0.0063000000000000" 94 | }, 95 | "price_monthly": { 96 | "net": "3.8500000000", 97 | "gross": "3.8500000000000000" 98 | } 99 | } 100 | ], 101 | "storage_type": "local", 102 | "cpu_type": "shared", 103 | "architecture": "x86", 104 | "included_traffic": 21990232555520, 105 | "deprecation": null 106 | } 107 | } 108 | ``` 109 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/servers.md: -------------------------------------------------------------------------------- 1 | # 🖥️ Servers 2 | 3 | Servers are virtual machines that can be provisioned. 4 | 5 | ## Get all Servers 6 | 7 | Returns all existing Server objects 8 | 9 | ```csharp 10 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 11 | 12 | // Get All 13 | List list = await hetznerCloudClient.Server.Get(); 14 | ``` 15 | 16 | ## Get a Server 17 | 18 | Returns a specific Server object. The Server must exist inside the Project 19 | 20 | ```csharp 21 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 22 | 23 | long serverId = 39447794; 24 | 25 | // Get One 26 | Server server = await hetznerCloudClient.Server.Get(serverId); 27 | ``` 28 | 29 | ## Create a Server (Simple) 30 | 31 | Creates a new Server. Returns preliminary information about the Server as well as an Action that covers progress of creation. 32 | 33 | Creating a server is pretty straightforward. We can specify the basics like name, image, location, or get more detailed, indicating whether we'll enable IPv4, IPv6, or specifying if it'll be within a private network. We can set SSH keys, decide if it should be associated with a volume, or even kick off a startup script using [Cloud config](https://community.hetzner.com/tutorials/basic-cloud-config). 34 | 35 | The minimum required to create the server is the [location](https://github.com/ljchuello/HetznerCloud.Api/wiki/Location), the [image](https://github.com/ljchuello/HetznerCloud.Api/wiki/Image), the server name, and the [server type](https://github.com/ljchuello/HetznerCloud.Api/wiki/Servers-Types) 36 | 37 | In this example, we'll specify the minimum to create a server. 38 | 39 | ```csharp 40 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("apiKey"); 41 | 42 | long datacenterId = 4; // ID of Datacenter to create Server 43 | long imageId = 45557056; // ID or name of the Image the Server is created from 44 | string name = "name-example"; // Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 45 | long serverTypeId = 22; // ID or name of the Image the Server is created from 46 | Server server = await hetznerCloudClient.Server.Create(datacenterId, imageId, name, serverTypeId); 47 | ``` 48 | 49 | Additionally, the [eDataCenter](https://github.com/ljchuello/HetznerCloud.Api/wiki/Datacenter#edatacenter) enum has been created, aiming to standardize resource creation throughout the Hetzner environment. It can be used for server creation as follows 50 | 51 | ```csharp 52 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 53 | 54 | eDataCenter eDataCenter = eDataCenter.ash; // Enum for the data center where it will be created 55 | long imageId = 45557056; // ID or name of the Image the Server is created from 56 | string name = "name-example"; // Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 57 | long serverTypeId = 22; // ID or name of the Image the Server is created from 58 | Server server = await hetznerCloudClient.Server.Create(eDataCenter, imageId, name, serverTypeId); 59 | ``` 60 | 61 | ## Create a Server (Complete) 62 | 63 | In addition to creating a server (simple), we can specify every detail of the server's resources. This includes indicating whether to enable IPv4, IPv6, passing a list of network IDs, SSH key IDs, specifying the volumes to mount, and even including it in a "placement group." We can also indicate the startup script with Cloud-Init scripts 64 | 65 | ```csharp 66 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 67 | 68 | long datacenterId = 4; // ID of Datacenter to create Server 69 | long imageId = 45557056; // ID or name of the Image the Server is created from 70 | string name = "name-example"; // Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 71 | long serverTypeId = 22; // ID or name of the Image the Server is created from 72 | // Optional; 73 | List privateNetoworksIds = new List { 3562839 }; // List containing the IDs of the private networks 74 | List sshKeysIds = new List { 13121954, 16371855 }; // List containing the SSH keys that the resource will use 75 | List volumesIds = new List { 100090124 }; // List containing the IDs of the volumes that will be attached to the server and mounted automatically 76 | long placementGroupId = 270736; // ID or Placement Group 77 | Server server = await hetznerCloudClient.Server.Create( 78 | datacenterId, 79 | imageId, 80 | name, 81 | serverTypeId, 82 | ipv4: true, 83 | ipv6: true, 84 | privateNetoworksIds: privateNetoworksIds, 85 | sshKeysIds: sshKeysIds, 86 | volumesIds: volumesIds, 87 | placementGroupId: placementGroupId, 88 | userData: "#cloud-config" + 89 | "\npackages:" + 90 | "\n- cadaver" + 91 | "\n- unzip" + 92 | "\npackage_update: true" + 93 | "\npackage_upgrade: true"); 94 | ``` 95 | 96 | And just like in the simple creation, here you can also replace `LocationId` with `eDataCenter` to make the creation process simpler 97 | 98 | ```csharp 99 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 100 | 101 | eDataCenter eDataCenter = eDataCenter.ash; // Enum for the data center where it will be created 102 | long imageId = 45557056; // ID or name of the Image the Server is created from 103 | string name = "name-example"; // Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 104 | long serverTypeId = 22; // ID or name of the Image the Server is created from 105 | // Optional; 106 | List privateNetoworksIds = new List { 3562839 }; // List containing the IDs of the private networks 107 | List sshKeysIds = new List { 13121954, 16371855 }; // List containing the SSH keys that the resource will use 108 | List volumesIds = new List { 100090124 }; // List containing the IDs of the volumes that will be attached to the server and mounted automatically 109 | long placementGroupId = 270736; // ID or Placement Group 110 | Server server = await hetznerCloudClient.Server.Create( 111 | eDataCenter, 112 | imageId, 113 | name, 114 | serverTypeId, 115 | ipv4: true, 116 | ipv6: true, 117 | privateNetoworksIds: privateNetoworksIds, 118 | sshKeysIds: sshKeysIds, 119 | volumesIds: volumesIds, 120 | placementGroupId: placementGroupId, 121 | userData: "#cloud-config" + 122 | "\npackages:" + 123 | "\n- cadaver" + 124 | "\n- unzip" + 125 | "\npackage_update: true" + 126 | "\npackage_upgrade: true"); 127 | ``` 128 | 129 | ## Update a Server 130 | 131 | Updates a Server. You can update a Server’s name. 132 | 133 | ```csharp 134 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 135 | 136 | // Get one server 137 | Server server = await hetznerCloudClient.Server.Get(39706661); 138 | 139 | // Change name 140 | server.Name = "new-name"; 141 | 142 | // Update 143 | server = await hetznerCloudClient.Server.Update(server); 144 | ``` 145 | 146 | ## **Note:** 147 | 148 | Person asking: Can you only modify the name in the `api.hetzner.cloud/v1/servers/{id}` endpoint? 149 | 150 | Person answering: Yes! 151 | 152 | Person asking: 😐 153 | 154 | All other actions that affect or interact with the server can be found in Servers Actions. 155 | 156 | ## Delete a Server 157 | 158 | Deletes a Server. This immediately removes the Server from your account, and it is no longer accessible. Any resources attached to the server (like Volumes, Primary IPs, Floating IPs, Firewalls, Placement Groups) are detached while the server is deleted. 159 | 160 | ```csharp 161 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 162 | 163 | // Get one server 164 | Server server = await hetznerCloudClient.Server.Get(39707117); 165 | 166 | // Delete 167 | await hetznerCloudClient.Server.Delete(server); 168 | ``` 169 | 170 | You can also delete by passing the Server ID instead of the Server object 171 | 172 | ```csharp 173 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 174 | 175 | // Delete 176 | await hetznerCloudClient.Server.Delete(39707117); 177 | ``` 178 | 179 | ## **JSON** 180 | 181 | ```json 182 | { 183 | "server": { 184 | "id": 39707330, 185 | "name": "debian-2gb-ash-1", 186 | "status": "running", 187 | "created": "2023-11-23T02:17:38+00:00", 188 | "public_net": { 189 | "ipv4": { 190 | "ip": "5.161.64.45", 191 | "blocked": false, 192 | "dns_ptr": "static.45.64.161.5.clients.your-server.de", 193 | "id": 44310536 194 | }, 195 | "ipv6": { 196 | "ip": "2a01:4ff:f0:c883::/64", 197 | "blocked": false, 198 | "dns_ptr": [], 199 | "id": 44310537 200 | }, 201 | "floating_ips": [], 202 | "firewalls": [ 203 | { 204 | "id": 1138264, 205 | "status": "applied" 206 | } 207 | ] 208 | }, 209 | "private_net": [ 210 | { 211 | "network": 3588651, 212 | "ip": "10.0.0.2", 213 | "alias_ips": [], 214 | "mac_address": "86:00:00:68:b5:2e" 215 | } 216 | ], 217 | "server_type": { 218 | "id": 22, 219 | "name": "cpx11", 220 | "description": "CPX 11", 221 | "cores": 2, 222 | "memory": 2.0, 223 | "disk": 40, 224 | "deprecated": false, 225 | "prices": [ 226 | { 227 | "location": "ash", 228 | "price_hourly": { 229 | "net": "0.0063000000", 230 | "gross": "0.0063000000000000" 231 | }, 232 | "price_monthly": { 233 | "net": "3.8500000000", 234 | "gross": "3.8500000000000000" 235 | } 236 | }, 237 | { 238 | "location": "hel1", 239 | "price_hourly": { 240 | "net": "0.0063000000", 241 | "gross": "0.0063000000000000" 242 | }, 243 | "price_monthly": { 244 | "net": "3.8500000000", 245 | "gross": "3.8500000000000000" 246 | } 247 | }, 248 | { 249 | "location": "nbg1", 250 | "price_hourly": { 251 | "net": "0.0063000000", 252 | "gross": "0.0063000000000000" 253 | }, 254 | "price_monthly": { 255 | "net": "3.8500000000", 256 | "gross": "3.8500000000000000" 257 | } 258 | }, 259 | { 260 | "location": "hil", 261 | "price_hourly": { 262 | "net": "0.0063000000", 263 | "gross": "0.0063000000000000" 264 | }, 265 | "price_monthly": { 266 | "net": "3.8500000000", 267 | "gross": "3.8500000000000000" 268 | } 269 | }, 270 | { 271 | "location": "fsn1", 272 | "price_hourly": { 273 | "net": "0.0063000000", 274 | "gross": "0.0063000000000000" 275 | }, 276 | "price_monthly": { 277 | "net": "3.8500000000", 278 | "gross": "3.8500000000000000" 279 | } 280 | } 281 | ], 282 | "storage_type": "local", 283 | "cpu_type": "shared", 284 | "architecture": "x86", 285 | "included_traffic": 21990232555520, 286 | "deprecation": null 287 | }, 288 | "datacenter": { 289 | "id": 5, 290 | "name": "ash-dc1", 291 | "description": "Ashburn virtual DC 1", 292 | "location": { 293 | "id": 4, 294 | "name": "ash", 295 | "description": "Ashburn, VA", 296 | "country": "US", 297 | "city": "Ashburn, VA", 298 | "latitude": 39.045821, 299 | "longitude": -77.487073, 300 | "network_zone": "us-east" 301 | }, 302 | "server_types": { 303 | "supported": [ 304 | 1, 305 | 3, 306 | 5, 307 | 7, 308 | 9, 309 | 22, 310 | 23, 311 | 24, 312 | 25, 313 | 26, 314 | 45, 315 | 93, 316 | 94, 317 | 95, 318 | 96, 319 | 97, 320 | 98, 321 | 99, 322 | 100, 323 | 101 324 | ], 325 | "available": [ 326 | 22, 327 | 23, 328 | 24, 329 | 25, 330 | 26, 331 | 96, 332 | 97, 333 | 98, 334 | 99, 335 | 100, 336 | 101 337 | ], 338 | "available_for_migration": [ 339 | 22, 340 | 23, 341 | 24, 342 | 25, 343 | 26, 344 | 96, 345 | 97, 346 | 98, 347 | 99, 348 | 100, 349 | 101 350 | ] 351 | } 352 | }, 353 | "image": { 354 | "id": 45557056, 355 | "type": "system", 356 | "status": "available", 357 | "name": "debian-11", 358 | "description": "Debian 11", 359 | "image_size": null, 360 | "disk_size": 5, 361 | "created": "2021-08-16T11:12:01+00:00", 362 | "created_from": null, 363 | "bound_to": null, 364 | "os_flavor": "debian", 365 | "os_version": "11", 366 | "rapid_deploy": true, 367 | "protection": { 368 | "delete": false 369 | }, 370 | "deprecated": null, 371 | "labels": {}, 372 | "deleted": null, 373 | "architecture": "x86" 374 | }, 375 | "iso": null, 376 | "rescue_enabled": false, 377 | "locked": false, 378 | "backup_window": "02-06", 379 | "outgoing_traffic": null, 380 | "ingoing_traffic": null, 381 | "included_traffic": 21990232555520, 382 | "protection": { 383 | "delete": false, 384 | "rebuild": false 385 | }, 386 | "labels": {}, 387 | "volumes": [ 388 | 100110783 389 | ], 390 | "load_balancers": [], 391 | "primary_disk_size": 40, 392 | "placement_group": { 393 | "id": 270756, 394 | "name": "placement-group-1", 395 | "labels": {}, 396 | "type": "spread", 397 | "created": "2023-11-23T02:16:36.803259+00:00", 398 | "servers": [ 399 | 39707330 400 | ] 401 | } 402 | } 403 | } 404 | ``` 405 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/ssh-keys.md: -------------------------------------------------------------------------------- 1 | # 🔐 SSH Keys 2 | 3 | SSH keys are public keys you provide to the cloud system. They can be injected into Servers at creation time. We highly recommend that you use keys instead of passwords to manage your Servers. 4 | 5 | ## Get all SSH keys 6 | 7 | Returns all SSH key objects. 8 | 9 | ```csharp 10 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 11 | 12 | List list = await hetznerCloudClient.SshKey.Get(); 13 | ``` 14 | 15 | ## Get a SSH key 16 | 17 | Returns a specific SSH key object. 18 | 19 | ```csharp 20 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 21 | 22 | long sshKeyId = 13121954; 23 | 24 | SshKey sshKey = await hetznerCloudClient.SshKey.Get(sshKeyId); 25 | ``` 26 | 27 | ## Create an SSH key 28 | 29 | Creates a new SSH key with the given name and public\_key. Once an SSH key is created, it can be used in other calls such as creating Servers. 30 | 31 | ```csharp 32 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 33 | 34 | // We rely on the 'SshKeyGenerator' library to generate SSH credentials. 35 | SshKeyGenerator.SshKeyGenerator sshKeyGenerator = new SshKeyGenerator.SshKeyGenerator(2048); 36 | 37 | string name = $"name"; 38 | string pub = sshKeyGenerator.ToRfcPublicKey($"{Guid.NewGuid()}"); 39 | 40 | SshKey sshKey = await hetznerCloudClient.SshKey.Create(name, pub); 41 | ``` 42 | 43 | ## Update an SSH key 44 | 45 | Updates an SSH key. You can update an SSH key name and an SSH key labels. 46 | 47 | ```csharp 48 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 49 | 50 | // Get 51 | SshKey sshKey = await hetznerCloudClient.SshKey.Get(16725981); 52 | 53 | // Change name 54 | sshKey.Name = $"new-name-{Guid.NewGuid()}"; 55 | 56 | // Update 57 | sshKey = await hetznerCloudClient.SshKey.Update(sshKey); 58 | ``` 59 | 60 | ## Delete a Volume 61 | 62 | Deletes a volume. All Volume data is irreversibly destroyed. The Volume must not be attached to a Server and it must not have delete protection enabled. 63 | 64 | ```csharp 65 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 66 | 67 | // Get 68 | SshKey sshKey = await hetznerCloudClient.SshKey.Get(16725981); 69 | 70 | // You can delete it by passing the object as a parameter 71 | await hetznerCloudClient.SshKey.Delete(sshKey); 72 | 73 | // You can also delete it by passing the ID as a parameter. 74 | await hetznerCloudClient.SshKey.Delete(16725981); 75 | ``` 76 | 77 | ## **JSON** 78 | 79 | ```json 80 | { 81 | "ssh_key": { 82 | "id": 16371855, 83 | "name": "MT5", 84 | "fingerprint": "5b:3a:fe:c9:88:24:6a:c8:ed:ff:7b:38:07:03:40:4d", 85 | "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsRjE/G6WYoLQgxjP8h00fwEowwiJ4EgB9HHrnIy3Z5JthxrKJe5RQSSUa5Qsz8+OgJtDVAKn++twM9tcF63Kna8YpEgvZSAkEEcz14a0KuuWpe/Kh4qw2jJTyuk6pmdT9+gMMq6X9IyrfkwgyPsCJEjVxsDHAWU2Ym5LA+e7WRQtoq+JNVzAJ0cNIU5/gEnYVz8KGrsUkBDCFeoBenwl8ss+nwumNo9Lnf2TCOegBFGph0m+wrRzE8Y1NnRoanuSVV0zSwZXlrhdf0Jqz8CX+cDjN9r6p0HIH+dVCY1iBQvYsE28Cs13WfpY/wfSjuKtjYE2p6jmZtrdDduXC+Qn5", 86 | "labels": {}, 87 | "created": "2023-10-24T01:58:43+00:00" 88 | } 89 | } 90 | ``` 91 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/volumes/README.md: -------------------------------------------------------------------------------- 1 | # 📦 Volumes 2 | 3 | A Volume is a highly-available, scalable, and SSD-based block storage for Servers. 4 | 5 | Pricing for Volumes depends on the Volume size and Location, not the actual used storage. 6 | 7 | Please see [Hetzner Docs](https://docs.hetzner.com/cloud/#Volumes) for more details about Volumes. 8 | 9 | ## Get all Volumes 10 | 11 | Gets all existing Volumes that you have available. 12 | 13 | ```csharp 14 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 15 | 16 | // Get All 17 | List listVolume = await hetznerCloudClient.Volume.Get(); 18 | ``` 19 | 20 | ## Get a Volume 21 | 22 | Gets a specific Volume object. 23 | 24 | ```csharp 25 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 26 | 27 | long volumeId = 100051904; 28 | 29 | // Get 30 | Volume volume = await hetznerCloudClient.Volume.Get(volumeId); 31 | ``` 32 | 33 | ## Update a Volume 34 | 35 | Updates the Volume properties. 36 | 37 | ```csharp 38 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 39 | 40 | // Get 41 | Volume volume = await hetznerCloudClient.Volume.Get(100051904); 42 | 43 | // Change name 44 | volume.Name = "new-name"; 45 | 46 | // Set 47 | volume = await hetznerCloudClient.Volume.Update(volume); 48 | ``` 49 | 50 | ## Delete a Volume 51 | 52 | Deletes a volume. All Volume data is irreversibly destroyed. The Volume must not be attached to a Server and it must not have delete protection enabled. 53 | 54 | ```csharp 55 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 56 | 57 | // Get 58 | Volume volume = await hetznerCloudClient.Volume.Get(100051904); 59 | 60 | // You can delete it by passing the Volume as a parameter 61 | await hetznerCloudClient.Volume.Delete(volume); 62 | 63 | // You can also delete it by passing the Volume ID as a parameter. 64 | await hetznerCloudClient.Volume.Delete(100051904); 65 | ``` 66 | 67 | ## **JSON** 68 | 69 | ```json 70 | { 71 | "volume": { 72 | "created": "2023-11-05T14:36:19Z", 73 | "format": "ext4", 74 | "id": 100056342, 75 | "labels": {}, 76 | "linux_device": "/dev/disk/by-id/scsi-0HC_Volume_100056342", 77 | "location": { 78 | "city": "Ashburn, VA", 79 | "country": "US", 80 | "description": "Ashburn, VA", 81 | "id": 4, 82 | "latitude": 39.045821, 83 | "longitude": -77.487073, 84 | "name": "ash", 85 | "network_zone": "us-east" 86 | }, 87 | "name": "volume-ash-1", 88 | "protection": { 89 | "delete": false 90 | }, 91 | "server": 38976603, 92 | "size": 101, 93 | "status": "available" 94 | } 95 | } 96 | ``` 97 | -------------------------------------------------------------------------------- /Docs/functions-and-methods/volumes/volumes-actions.md: -------------------------------------------------------------------------------- 1 | # Volumes Actions 2 | 3 | ## Attach Volume to a Server 4 | 5 | Attaches a Volume to a Server. Works only if the Server is in the same Location as the Volume. 6 | 7 | ```csharp 8 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 9 | 10 | long volumeId = 100051962; 11 | long serverId = 38911232; 12 | 13 | Action action = await hetznerCloudClient.VolumeAction.Attach(volumeId, serverId); 14 | ``` 15 | 16 | ## Detach Volume 17 | 18 | Detaches a Volume from the Server it’s attached to. You may attach it to a Server again at a later time. 19 | 20 | ```csharp 21 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 22 | 23 | long volumeId = 100051962; 24 | 25 | Action action = await hetznerCloudClient.VolumeAction.Detach(volumeId); 26 | ``` 27 | 28 | ## Resize Volume 29 | 30 | Changes the size of a Volume. Note that downsizing a Volume is not possible. 31 | 32 | ```csharp 33 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 34 | 35 | long volumeId = 100051962; 36 | long size = 101; // Volume size in GB 37 | Action action = await hetznerCloudClient.VolumeAction.Resize(volumeId, size); 38 | ``` 39 | 40 | ## Change Volume Protection 41 | 42 | Changes the protection configuration of a Volume. 43 | 44 | ```csharp 45 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 46 | 47 | long volumeId = 100051962; 48 | bool protection = true; // True => Enable protection | False => Disable protection 49 | Action action = await hetznerCloudClient.VolumeAction.ChangeProtection(volumeId, protection); 50 | ``` 51 | 52 | ## Get all Actions for a Volume 53 | 54 | Returns all Action objects for a Volume. 55 | 56 | ```csharp 57 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 58 | 59 | long volumeId = 100051962; 60 | 61 | List list = await hetznerCloudClient.VolumeAction.GetAllActions(volumeId); 62 | ``` 63 | 64 | ## Get an Action for a Volume 65 | 66 | Returns a specific Action for a Volume. 67 | 68 | ```csharp 69 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 70 | 71 | long volumeId = 100051962; 72 | long actionId = 1236866267; 73 | 74 | Action action = await hetznerCloudClient.VolumeAction.GetAction(volumeId, actionId); 75 | ``` 76 | 77 | ## Get all Actions 78 | 79 | Returns all Action objects. 80 | 81 | ```csharp 82 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 83 | 84 | List list = await hetznerCloudClient.VolumeAction.GetAllActions(); 85 | ``` 86 | 87 | ## Get an Action 88 | 89 | Returns a specific Action. 90 | 91 | ```csharp 92 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 93 | 94 | long actionId = 1236866267; 95 | 96 | Action action = await hetznerCloudClient.VolumeAction.GetAction(actionId); 97 | ``` 98 | -------------------------------------------------------------------------------- /Docs/overview/compatibility.md: -------------------------------------------------------------------------------- 1 | # 🔗 Compatibility 2 | 3 | This library is developed in .NET Standard 2.0 and is compatible with all .NET, .NET Core and .NET Framework, it can also be used in Console projects, Web API, Class Library and even with Blazor WASM . 4 | 5 | | .NET implementation | Version support | 6 | | ------------------- | --------------------------------------------- | 7 | | .NET and .NET Core | 2.0, 2.1, 2.2, 3.0, 3.1, 5.0, 6.0, 7.0, 8.0 | 8 | | .NET Framework | 4.6.1 2, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 | 9 | -------------------------------------------------------------------------------- /Docs/overview/installation.md: -------------------------------------------------------------------------------- 1 | # 🔧 Installation 2 | 3 | To install you must go to Nuget package manager and search for **HetznerCloud.API** and then install. 4 | 5 | [**NuGet Package**](https://www.nuget.org/packages/HetznerCloud.API/) 6 | 7 | ```powershell 8 | PM> dotnet add package HetznerCloud.API 9 | ``` 10 | -------------------------------------------------------------------------------- /Docs/overview/need-help-or-have-questions.md: -------------------------------------------------------------------------------- 1 | # 🆘 Need help or have questions? 2 | 3 | If you encounter any issues or have questions related to `HetznerCloud.API`, we're here to help. 🙌 The fastest and most effective way to get support is to open an issue in our repository. 4 | 5 | #### 📝 How to Open an Issue? 6 | 7 | 1. Visit the [HetznerCloud.AP](https://github.com/ljchuello/HetznerCloud.API)I repository on GitHub. 🌐 8 | 2. Go to the **Issues** section. 📊 9 | 3. Click on **New Issue**. 🆕 10 | 4. Provide a descriptive title and detail your problem or question in the issue's body. 📝 The more information you provide, the better we can assist you. 11 | 5. Once you're done, click on **Submit new issue**. ✔️ 12 | 13 | Our team will review your issue and provide you with a response or solution as soon as possible. 🏃‍♂️💨 Your feedback and questions are valuable for the continuous improvement of `HetznerCloud.API`! 🌟 14 | -------------------------------------------------------------------------------- /HetznerCloudApi.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.7.34031.279 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HetznerCloudApi", "HetznerCloudApi\HetznerCloudApi.csproj", "{D762351B-635F-4372-8FF0-9210A4F657AF}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{C4B88AB3-2C02-41BC-B314-9129C65ECE57}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elementos de la solución", "Elementos de la solución", "{0D3D759E-7536-47D4-9DDA-C63A692B39AA}" 11 | ProjectSection(SolutionItems) = preProject 12 | CHANGELOG.md = CHANGELOG.md 13 | ..\..\Users\LJChuello\Pictures\icon_128.png = ..\..\Users\LJChuello\Pictures\icon_128.png 14 | LICENSE = LICENSE 15 | README.md = README.md 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {D762351B-635F-4372-8FF0-9210A4F657AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {D762351B-635F-4372-8FF0-9210A4F657AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {D762351B-635F-4372-8FF0-9210A4F657AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {D762351B-635F-4372-8FF0-9210A4F657AF}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {C4B88AB3-2C02-41BC-B314-9129C65ECE57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {C4B88AB3-2C02-41BC-B314-9129C65ECE57}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {C4B88AB3-2C02-41BC-B314-9129C65ECE57}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {C4B88AB3-2C02-41BC-B314-9129C65ECE57}.Release|Any CPU.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | GlobalSection(ExtensibilityGlobals) = postSolution 37 | SolutionGuid = {A7067DA4-665F-4936-A300-BE3438ED40EE} 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/ActionClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using HetznerCloudApi.Object.Action; 6 | using HetznerCloudApi.Object.Action.Get; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class ActionClient 11 | { 12 | private readonly string _token; 13 | 14 | public ActionClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Get all Actions 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List list = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Action row in response.Actions) 37 | { 38 | list.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return list; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Returns a specific Action object. 52 | /// 53 | /// ID of the Resource 54 | /// 55 | public async Task Get(long actionId) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/actions/{actionId}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 63 | 64 | // Return 65 | return action; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/DatacenterClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using HetznerCloudApi.Object.Datacenter; 5 | using HetznerCloudApi.Object.Datacenter.Get; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class DatacenterClient 11 | { 12 | private readonly string _token; 13 | 14 | public DatacenterClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Returns all Datacenter objects. 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List listDatacenters = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/datacenters?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Datacenter row in response.Datacenters) 37 | { 38 | listDatacenters.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return listDatacenters; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Returns a specific Datacenter object 52 | /// 53 | /// ID of the Datacenter 54 | /// 55 | public async Task Get(long id) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/datacenters/{id}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Datacenter datacenter = JsonConvert.DeserializeObject($"{result["datacenter"]}") ?? new Datacenter(); 63 | 64 | // Return 65 | return datacenter; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/FirewallActionClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using HetznerCloudApi.Object.Action; 6 | using HetznerCloudApi.Object.Action.Get; 7 | using HetznerCloudApi.Object.Firewall; 8 | 9 | namespace HetznerCloudApi.Client 10 | { 11 | public class FirewallActionClient 12 | { 13 | private readonly string _token; 14 | 15 | public FirewallActionClient(string token) 16 | { 17 | _token = token; 18 | } 19 | 20 | /// 21 | /// Apply to Resources 22 | /// 23 | /// 24 | /// 25 | /// 26 | public async Task> ApplyToResources(long firewallId, long serverId) 27 | { 28 | // Preparing raw 29 | string raw = $"{{ \"apply_to\": [ {{ \"server\": {{ \"id\": {serverId} }}, \"type\": \"server\" }} ] }}"; 30 | 31 | // Send update 32 | string jsonResponse = await Core.SendPostRequest(_token, $"/firewalls/{firewallId}/actions/apply_to_resources", raw); 33 | 34 | // Return 35 | JObject result = JObject.Parse(jsonResponse); 36 | return JsonConvert.DeserializeObject>($"{result["actions"]}") ?? new List(); 37 | } 38 | 39 | /// 40 | /// Removes one Firewall from multiple resources. 41 | /// 42 | /// 43 | /// 44 | /// 45 | public async Task> RemoveFromResources(long firewallId, long serverId) 46 | { 47 | // Preparing raw 48 | string raw = $"{{ \"remove_from\": [ {{ \"server\": {{ \"id\": {serverId} }}, \"type\": \"server\" }} ] }}"; 49 | 50 | // Send update 51 | string jsonResponse = await Core.SendPostRequest(_token, $"/firewalls/{firewallId}/actions/remove_from_resources", raw); 52 | 53 | // Return 54 | JObject result = JObject.Parse(jsonResponse); 55 | return JsonConvert.DeserializeObject>($"{result["actions"]}") ?? new List(); 56 | } 57 | 58 | /// 59 | /// Sets the rules of a Firewall. 60 | /// 61 | /// 62 | /// 63 | /// 64 | public async Task> SetRules(Firewall firewall, List rules) 65 | { 66 | var temp = new 67 | { 68 | rules = rules 69 | }; 70 | 71 | // Preparing raw 72 | string raw = JsonConvert.SerializeObject(temp, Formatting.Indented); 73 | 74 | // Send update 75 | string jsonResponse = await Core.SendPostRequest(_token, $"/firewalls/{firewall.Id}/actions/set_rules", raw); 76 | 77 | // Return 78 | JObject result = JObject.Parse(jsonResponse); 79 | return JsonConvert.DeserializeObject>($"{result["actions"]}") ?? new List(); 80 | } 81 | 82 | /// 83 | /// Returns all Action objects for a Firewall. 84 | /// 85 | /// ID of the Resource 86 | /// 87 | public async Task> GetAllActions(long firewallId) 88 | { 89 | List list = new List(); 90 | long page = 0; 91 | while (true) 92 | { 93 | // Nex 94 | page++; 95 | 96 | // Get list 97 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/firewalls/{firewallId}/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 98 | 99 | // Run 100 | foreach (Action row in response.Actions) 101 | { 102 | list.Add(row); 103 | } 104 | 105 | // Finish? 106 | if (response.Meta.Pagination.NextPage == 0) 107 | { 108 | // Yes, finish 109 | return list; 110 | } 111 | } 112 | } 113 | 114 | /// 115 | /// Returns a specific Action for a Firewall. 116 | /// 117 | /// ID of the Firewall 118 | /// ID of the Action 119 | /// 120 | public async Task GetAction(long firewallId, long actionId) 121 | { 122 | // Get list 123 | string json = await Core.SendGetRequest(_token, $"/firewalls/{firewallId}/actions/{actionId}"); 124 | 125 | // Set 126 | JObject result = JObject.Parse(json); 127 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 128 | 129 | // Return 130 | return action; 131 | } 132 | 133 | /// 134 | /// Returns all Action objects 135 | /// 136 | /// 137 | public async Task> GetAllActions() 138 | { 139 | List list = new List(); 140 | long page = 0; 141 | while (true) 142 | { 143 | // Nex 144 | page++; 145 | 146 | // Get list 147 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/firewalls/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 148 | 149 | // Run 150 | foreach (Action row in response.Actions) 151 | { 152 | list.Add(row); 153 | } 154 | 155 | // Finish? 156 | if (response.Meta.Pagination.NextPage == 0) 157 | { 158 | // Yes, finish 159 | return list; 160 | } 161 | } 162 | } 163 | 164 | /// 165 | /// Returns a specific Action object 166 | /// 167 | /// ID of the Resource 168 | /// 169 | public async Task GetAction(long actionId) 170 | { 171 | // Get list 172 | string json = await Core.SendGetRequest(_token, $"/firewalls/actions/{actionId}"); 173 | 174 | // Set 175 | JObject result = JObject.Parse(json); 176 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 177 | 178 | // Return 179 | return action; 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/FirewallClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using HetznerCloudApi.Object.Firewall; 5 | using HetznerCloudApi.Object.Firewall.Get; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class FirewallClient 11 | { 12 | private readonly string _token; 13 | 14 | public FirewallClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Returns all Firewall objects. 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List list = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/firewalls?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Firewall row in response.Firewalls) 37 | { 38 | list.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return list; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Gets a specific Firewall object. 52 | /// 53 | /// ID of the resource 54 | /// 55 | public async Task Get(long id) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/firewalls/{id}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Firewall firewall = JsonConvert.DeserializeObject($"{result["firewall"]}") ?? new Firewall(); 63 | 64 | // Return 65 | return firewall; 66 | } 67 | 68 | /// 69 | /// Creates a new Firewall. 70 | /// 71 | /// Name of the Firewall 72 | /// 73 | public async Task Create(string name) 74 | { 75 | // Preparing raw 76 | string raw = $"{{ \"name\": \"{name}\" }}"; 77 | 78 | // Send post 79 | string jsonResponse = await Core.SendPostRequest(_token, "/firewalls", raw); 80 | 81 | // Return 82 | JObject result = JObject.Parse(jsonResponse); 83 | return JsonConvert.DeserializeObject($"{result["firewall"]}") ?? new Firewall(); 84 | } 85 | 86 | /// 87 | /// Updates the Firewall. 88 | /// 89 | /// 90 | /// 91 | public async Task Update(Firewall firewall) 92 | { 93 | // Preparing raw 94 | string raw = $"{{\"name\":\"{firewall.Name}\"}}"; 95 | 96 | // Send update 97 | string jsonResponse = await Core.SendPutRequest(_token, $"/firewalls/{firewall.Id}", raw); 98 | 99 | // Return 100 | JObject result = JObject.Parse(jsonResponse); 101 | return JsonConvert.DeserializeObject($"{result["firewall"]}") ?? new Firewall(); 102 | } 103 | 104 | /// 105 | /// Deletes a Firewall. 106 | /// 107 | /// 108 | /// 109 | public async Task Delete(long id) 110 | { 111 | await Core.SendDeleteRequest(_token, $"/firewalls/{id}"); 112 | } 113 | 114 | /// 115 | /// Deletes a Firewall. 116 | /// 117 | /// 118 | /// 119 | public async Task Delete(Firewall firewall) 120 | { 121 | await Delete(firewall.Id); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/ImageClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using HetznerCloudApi.Object.Image; 5 | using HetznerCloudApi.Object.Image.Get; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class ImageClient 11 | { 12 | private readonly string _token; 13 | 14 | public ImageClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Returns all Image objects. 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List listImage = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/images?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Image row in response.Images) 37 | { 38 | listImage.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return listImage; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Returns a specific Image object 52 | /// 53 | /// ID of the Image 54 | /// 55 | public async Task Get(long id) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/images/{id}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Image image = JsonConvert.DeserializeObject($"{result["image"]}") ?? new Image(); 63 | 64 | // Return 65 | return image; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/LocationClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using HetznerCloudApi.Object.Location; 5 | using HetznerCloudApi.Object.Location.Get; 6 | using Newtonsoft.Json.Linq; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class LocationClient 11 | { 12 | private readonly string _token; 13 | 14 | public LocationClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Returns all Locations objects. 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List listImage = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/locations?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Location row in response.Locations) 37 | { 38 | listImage.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return listImage; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Returns a specific Location object 52 | /// 53 | /// ID of the Location 54 | /// 55 | public async Task Get(long id) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/locations/{id}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Location location = JsonConvert.DeserializeObject($"{result["location"]}") ?? new Location(); 63 | 64 | // Return 65 | return location; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/NetworkActionClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using HetznerCloudApi.Object.Action; 6 | using HetznerCloudApi.Object.Action.Get; 7 | using HetznerCloudApi.Object.Network; 8 | 9 | namespace HetznerCloudApi.Client 10 | { 11 | public class NetworkActionClient 12 | { 13 | private readonly string _token; 14 | 15 | public NetworkActionClient(string token) 16 | { 17 | _token = token; 18 | } 19 | 20 | /// 21 | /// Adds a new subnet object to the Network. If you do not specify an ip_range for the subnet we will automatically pick the first available /24 range for you if possible. 22 | /// 23 | /// ID of the Network 24 | /// Range to allocate IPs from. Must be a Subnet of the ip_range of the parent network object and must not overlap with any other subnets or with any destinations in routes. If the Subnet is of type vSwitch, it also can not overlap with any gateway in routes. Minimum Network size is /30. We suggest that you pick a bigger Network with a /24 netmask. 25 | /// Name of Network zone. The Location object contains the network_zone property each Location belongs to. 26 | /// 27 | public async Task AddSubnetToNetwork(long networkId, string ipRange, string networkZone) 28 | { 29 | // Preparing raw 30 | string raw = $"{{ \"ip_range\": \"{ipRange}\", \"network_zone\": \"{networkZone}\", \"type\": \"cloud\" }}"; 31 | 32 | // Send 33 | string jsonResponse = await Core.SendPostRequest(_token, $"/networks/{networkId}/actions/add_subnet", raw); 34 | 35 | // Return 36 | JObject result = JObject.Parse(jsonResponse); 37 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 38 | } 39 | 40 | /// 41 | /// Deletes a single subnet entry from a Network. You cannot delete subnets which still have Servers attached. If you have Servers attached you first need to detach all Servers that use IPs from this subnet before you can delete the subnet. 42 | /// 43 | /// ID of the Network 44 | /// IP range of subnet to delete 45 | /// 46 | public async Task DeleteSubnetFromNetwork(long networkId, string ipRange) 47 | { 48 | // Preparing raw 49 | string raw = $"{{ \"ip_range\": \"{ipRange}\" }}"; 50 | 51 | // Send 52 | string jsonResponse = await Core.SendPostRequest(_token, $"/networks/{networkId}/actions/delete_subnet", raw); 53 | 54 | // Return 55 | JObject result = JObject.Parse(jsonResponse); 56 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 57 | } 58 | 59 | /// 60 | /// Changes the protection configuration of a Network. 61 | /// 62 | /// ID of the Network 63 | /// If true, prevents the Network from being deleted 64 | /// 65 | public async Task ChangeProtection(long networkId, bool protection) 66 | { 67 | // Preparing raw 68 | string raw = $"{{ \"delete\": {(protection ? "true" : "false")} }}"; 69 | 70 | // Send post 71 | string jsonResponse = await Core.SendPostRequest(_token, $"/networks/{networkId}/actions/change_protection", raw); 72 | 73 | // Return 74 | JObject result = JObject.Parse(jsonResponse); 75 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 76 | } 77 | 78 | /// 79 | /// Get all Actions for a Network 80 | /// 81 | /// 82 | /// 83 | public async Task> GetAllActions(long networkId) 84 | { 85 | List list = new List(); 86 | long page = 0; 87 | while (true) 88 | { 89 | // Nex 90 | page++; 91 | 92 | // Get list 93 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/networks/{networkId}/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 94 | 95 | // Run 96 | foreach (Action row in response.Actions) 97 | { 98 | list.Add(row); 99 | } 100 | 101 | // Finish? 102 | if (response.Meta.Pagination.NextPage == 0) 103 | { 104 | // Yes, finish 105 | return list; 106 | } 107 | } 108 | } 109 | 110 | /// 111 | /// Get an Action for a Network 112 | /// 113 | /// 114 | /// 115 | /// 116 | public async Task GetAction(long networkId, long actionId) 117 | { 118 | // Get list 119 | string json = await Core.SendGetRequest(_token, $"/networks/{networkId}/actions/{actionId}"); 120 | 121 | // Set 122 | JObject result = JObject.Parse(json); 123 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 124 | 125 | // Return 126 | return action; 127 | } 128 | 129 | /// 130 | /// Get all Actions 131 | /// 132 | /// 133 | public async Task> GetAllActions() 134 | { 135 | List list = new List(); 136 | long page = 0; 137 | while (true) 138 | { 139 | // Nex 140 | page++; 141 | 142 | // Get list 143 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/networks/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 144 | 145 | // Run 146 | foreach (Action row in response.Actions) 147 | { 148 | list.Add(row); 149 | } 150 | 151 | // Finish? 152 | if (response.Meta.Pagination.NextPage == 0) 153 | { 154 | // Yes, finish 155 | return list; 156 | } 157 | } 158 | } 159 | 160 | /// 161 | /// Get an Action 162 | /// 163 | /// 164 | /// 165 | public async Task GetAction(long actionId) 166 | { 167 | // Get list 168 | string json = await Core.SendGetRequest(_token, $"/networks/actions/{actionId}"); 169 | 170 | // Set 171 | JObject result = JObject.Parse(json); 172 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 173 | 174 | // Return 175 | return action; 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/NetworkClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | using HetznerCloudApi.Object.Network; 6 | using HetznerCloudApi.Object.Network.Get; 7 | using HetznerCloudApi.Object.SshKey; 8 | 9 | namespace HetznerCloudApi.Client 10 | { 11 | public class NetworkClient 12 | { 13 | private readonly string _token; 14 | 15 | public NetworkClient(string token) 16 | { 17 | _token = token; 18 | } 19 | 20 | /// 21 | /// Gets all existing networks that you have available. 22 | /// 23 | /// 24 | public async Task> Get() 25 | { 26 | List list = new List(); 27 | long page = 0; 28 | while (true) 29 | { 30 | // Nex 31 | page++; 32 | 33 | // Get list 34 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/networks?page={page}&per_page={Core.PerPage}")) ?? new Response(); 35 | 36 | // Run 37 | foreach (Network row in response.Networks) 38 | { 39 | list.Add(row); 40 | } 41 | 42 | // Finish? 43 | if (response.Meta.Pagination.NextPage == 0) 44 | { 45 | // Yes, finish 46 | return list; 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// Gets a specific network object. 53 | /// 54 | /// 55 | /// 56 | public async Task Get(long id) 57 | { 58 | // Get list 59 | string json = await Core.SendGetRequest(_token, $"/networks/{id}"); 60 | 61 | // Set 62 | JObject result = JObject.Parse(json); 63 | Network network = JsonConvert.DeserializeObject($"{result["network"]}") ?? new Network(); 64 | 65 | // Return 66 | return network; 67 | } 68 | 69 | /// 70 | /// Creates a network with the specified ip_range. 71 | /// 72 | /// 73 | /// 74 | /// 75 | public async Task Create(string name, string ipRange) 76 | { 77 | // Preparing raw 78 | string raw = $"{{ \"name\": \"{name}\", \"ip_range\": \"{ipRange}\" }}"; 79 | 80 | // Send post 81 | string jsonResponse = await Core.SendPostRequest(_token, "/networks", raw); 82 | 83 | // Return 84 | JObject result = JObject.Parse(jsonResponse); 85 | return JsonConvert.DeserializeObject($"{result["network"]}") ?? new Network(); 86 | } 87 | 88 | /// 89 | /// Update the network name. 90 | /// 91 | /// 92 | /// 93 | public async Task Update(Network network) 94 | { 95 | // Preparing raw 96 | string raw = $"{{ \"name\": \"{network.Name}\" }}"; 97 | 98 | // Send post 99 | string jsonResponse = await Core.SendPutRequest(_token, $"/networks/{network.Id}", raw); 100 | 101 | // Return 102 | JObject result = JObject.Parse(jsonResponse); 103 | return JsonConvert.DeserializeObject($"{result["network"]}") ?? new Network(); 104 | } 105 | 106 | /// 107 | /// Delete a Network 108 | /// 109 | /// 110 | /// 111 | public async Task Delete(long id) 112 | { 113 | await Core.SendDeleteRequest(_token, $"/networks/{id}"); 114 | } 115 | 116 | /// 117 | /// Delete a Network 118 | /// 119 | /// 120 | /// 121 | public async Task Delete(Network network) 122 | { 123 | await Delete(network.Id); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/ServerClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | using HetznerCloudApi.Object.Server; 6 | using HetznerCloudApi.Object.Server.Get; 7 | using HetznerCloudApi.Object.Universal; 8 | using HetznerCloudApi.Object.Network; 9 | 10 | namespace HetznerCloudApi.Client 11 | { 12 | public class ServerClient 13 | { 14 | private readonly string _token; 15 | 16 | public ServerClient(string token) 17 | { 18 | _token = token; 19 | } 20 | 21 | public async Task> Get() 22 | { 23 | List list = new List(); 24 | long page = 0; 25 | while (true) 26 | { 27 | // Nex 28 | page++; 29 | 30 | // Get list 31 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/servers?page={page}&per_page={Core.PerPage}")) ?? new Response(); 32 | 33 | // Run 34 | foreach (Server row in response.Servers) 35 | { 36 | list.Add(row); 37 | } 38 | 39 | // Finish? 40 | if (response.Meta.Pagination.NextPage == 0) 41 | { 42 | // Yes, finish 43 | return list; 44 | } 45 | } 46 | } 47 | 48 | public async Task Get(long id) 49 | { 50 | // Get list 51 | string json = await Core.SendGetRequest(_token, $"/servers/{id}"); 52 | 53 | // Set 54 | JObject result = JObject.Parse(json); 55 | Server server = JsonConvert.DeserializeObject($"{result["server"]}") ?? null; 56 | 57 | // Return 58 | return server; 59 | } 60 | 61 | /// 62 | /// Creates a new Server. Returns preliminary information about the Server as well as an Action that covers progress of creation. 63 | /// 64 | /// Data center where the resource will be created 65 | /// ID or name of the Image the Server is created from 66 | /// Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 67 | /// ID or name of the Server type this Server should be created with 68 | /// Attach an IPv4 on the public NIC. If false, no IPv4 address will be attached. Defaults to true. 69 | /// Attach an IPv6 on the public NIC. If false, no IPv6 address will be attached. Defaults to true. 70 | /// Network IDs which should be attached to the Server private network interface at the creation time 71 | /// SSH key IDs which should be injected into the Server at creation time 72 | /// Volume IDs which should be attached to the Server at the creation time. Volumes must be in the same Location. 73 | /// ID of the Placement Group the server should be in 74 | /// Cloud-Init user data to use during Server creation. This field is limited to 32KiB. 75 | /// 76 | public async Task Create( 77 | eDataCenter dataCenter, 78 | long imageId, 79 | string name, 80 | long serverType, 81 | bool ipv4 = true, 82 | bool ipv6 = true, 83 | List privateNetoworksIds = default, 84 | List sshKeysIds = default, 85 | List volumesIds = default, 86 | long placementGroupId = 0, 87 | string userData = "") 88 | { 89 | 90 | // Location 91 | long datacenterId = 0; 92 | switch (dataCenter) 93 | { 94 | case eDataCenter.fsn1: 95 | datacenterId = 4; 96 | break; 97 | 98 | case eDataCenter.nbg1: 99 | datacenterId = 2; 100 | break; 101 | 102 | case eDataCenter.hel1: 103 | datacenterId = 3; 104 | break; 105 | 106 | case eDataCenter.ash: 107 | datacenterId = 5; 108 | break; 109 | 110 | case eDataCenter.hil: 111 | datacenterId = 6; 112 | break; 113 | } 114 | 115 | Post post = new Post 116 | { 117 | Datacenter = datacenterId, 118 | Image = imageId, 119 | Name = name, 120 | ServerType = serverType, 121 | PublicNet = new PublicNet 122 | { 123 | EnableIpv4 = ipv4, 124 | EnableIpv6 = ipv6 125 | }, 126 | Networks = privateNetoworksIds, 127 | SshKeys = sshKeysIds, 128 | UserData = userData 129 | }; 130 | 131 | if (volumesIds != null && volumesIds.Count > 0) 132 | { 133 | post.Volumes = volumesIds; 134 | post.Automount = true; 135 | } 136 | else 137 | { 138 | post.Volumes = null; 139 | post.Automount = null; 140 | } 141 | 142 | if (placementGroupId != 0) 143 | { 144 | post.PlacementGroup = placementGroupId; 145 | } 146 | else 147 | { 148 | post.PlacementGroup = null; 149 | } 150 | 151 | // Preparing raw 152 | string raw = JsonConvert.SerializeObject(post, Formatting.Indented); 153 | 154 | // Send post 155 | string jsonResponse = await Core.SendPostRequest(_token, "/servers", raw); 156 | 157 | // Return 158 | JObject result = JObject.Parse(jsonResponse); 159 | return JsonConvert.DeserializeObject($"{result["server"]}") ?? new Server(); 160 | } 161 | 162 | /// 163 | /// Creates a new Server. Returns preliminary information about the Server as well as an Action that covers progress of creation. 164 | /// 165 | /// ID of the Datacenter 166 | /// ID or name of the Image the Server is created from 167 | /// Name of the Server to create (must be unique per Project and a valid hostname as per RFC 1123) 168 | /// ID or name of the Server type this Server should be created with 169 | /// Attach an IPv4 on the public NIC. If false, no IPv4 address will be attached. Defaults to true. 170 | /// Attach an IPv6 on the public NIC. If false, no IPv6 address will be attached. Defaults to true. 171 | /// Network IDs which should be attached to the Server private network interface at the creation time 172 | /// SSH key IDs which should be injected into the Server at creation time 173 | /// Volume IDs which should be attached to the Server at the creation time. Volumes must be in the same Location. 174 | /// ID of the Placement Group the server should be in 175 | /// Cloud-Init user data to use during Server creation. This field is limited to 32KiB. 176 | /// 177 | public async Task Create( 178 | long datacenterId, 179 | long imageId, 180 | string name, 181 | long serverType, 182 | bool ipv4 = true, 183 | bool ipv6 = true, 184 | List privateNetoworksIds = default, 185 | List sshKeysIds = default, 186 | List volumesIds = default, 187 | long placementGroupId = 0, 188 | string userData = "") 189 | { 190 | 191 | Post post = new Post 192 | { 193 | Datacenter = datacenterId, 194 | Image = imageId, 195 | Name = name, 196 | ServerType = serverType, 197 | PublicNet = new PublicNet 198 | { 199 | EnableIpv4 = ipv4, 200 | EnableIpv6 = ipv6 201 | }, 202 | Networks = privateNetoworksIds, 203 | SshKeys = sshKeysIds, 204 | UserData = userData 205 | }; 206 | 207 | if (volumesIds != null && volumesIds.Count > 0) 208 | { 209 | post.Volumes = volumesIds; 210 | post.Automount = true; 211 | } 212 | else 213 | { 214 | post.Volumes = null; 215 | post.Automount = null; 216 | } 217 | 218 | if (placementGroupId != 0) 219 | { 220 | post.PlacementGroup = placementGroupId; 221 | } 222 | else 223 | { 224 | post.PlacementGroup = null; 225 | } 226 | 227 | // Preparing raw 228 | string raw = JsonConvert.SerializeObject(post, Formatting.Indented); 229 | 230 | // Send post 231 | string jsonResponse = await Core.SendPostRequest(_token, "/servers", raw); 232 | 233 | // Return 234 | JObject result = JObject.Parse(jsonResponse); 235 | return JsonConvert.DeserializeObject($"{result["server"]}") ?? new Server(); 236 | } 237 | 238 | /// 239 | /// Updates a Server. You can update a Server’s name. 240 | /// 241 | /// 242 | /// 243 | public async Task Update(Server server) 244 | { 245 | // Preparing raw 246 | string raw = $"{{ \"name\": \"{server.Name}\" }}"; 247 | 248 | // Send post 249 | string jsonResponse = await Core.SendPutRequest(_token, $"/servers/{server.Id}", raw); 250 | 251 | // Return 252 | JObject result = JObject.Parse(jsonResponse); 253 | return JsonConvert.DeserializeObject($"{result["server"]}") ?? new Server(); 254 | } 255 | 256 | /// 257 | /// Delete a Server 258 | /// 259 | /// 260 | /// 261 | public async Task Delete(long id) 262 | { 263 | await Core.SendDeleteRequest(_token, $"/servers/{id}"); 264 | } 265 | 266 | /// 267 | /// Delete a Server 268 | /// 269 | /// 270 | /// 271 | public async Task Delete(Server server) 272 | { 273 | await Delete(server.Id); 274 | } 275 | 276 | /// 277 | /// Class used to create the server 278 | /// 279 | private class Post 280 | { 281 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 282 | public string Name { get; set; } 283 | 284 | [JsonProperty("ssh_keys", NullValueHandling = NullValueHandling.Ignore)] 285 | public List SshKeys { get; set; } 286 | 287 | [JsonProperty("datacenter", NullValueHandling = NullValueHandling.Ignore)] 288 | public long Datacenter { get; set; } 289 | 290 | [JsonProperty("image", NullValueHandling = NullValueHandling.Ignore)] 291 | public long Image { get; set; } 292 | 293 | [JsonProperty("server_type", NullValueHandling = NullValueHandling.Ignore)] 294 | public long ServerType { get; set; } 295 | 296 | [JsonProperty("automount", NullValueHandling = NullValueHandling.Ignore)] 297 | public bool? Automount { get; set; } 298 | 299 | //[JsonProperty("firewalls", NullValueHandling = NullValueHandling.Ignore)] 300 | //public List Firewalls { get; set; } 301 | 302 | [JsonProperty("public_net", NullValueHandling = NullValueHandling.Ignore)] 303 | public PublicNet PublicNet { get; set; } 304 | 305 | [JsonProperty("networks", NullValueHandling = NullValueHandling.Ignore)] 306 | public List Networks { get; set; } 307 | 308 | [JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)] 309 | public List Volumes { get; set; } 310 | 311 | [JsonProperty("user_data", NullValueHandling = NullValueHandling.Ignore)] 312 | public string UserData { get; set; } 313 | 314 | [JsonProperty("placement_group", NullValueHandling = NullValueHandling.Ignore)] 315 | public long? PlacementGroup { get; set; } 316 | } 317 | 318 | private class PublicNet 319 | { 320 | [JsonProperty("enable_ipv4", NullValueHandling = NullValueHandling.Ignore)] 321 | public bool EnableIpv4 { get; set; } 322 | 323 | [JsonProperty("enable_ipv6", NullValueHandling = NullValueHandling.Ignore)] 324 | public bool EnableIpv6 { get; set; } 325 | } 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/ServerTypeClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Linq; 5 | using HetznerCloudApi.Object.ServerType; 6 | using HetznerCloudApi.Object.ServerType.Get; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class ServerTypeClient 11 | { 12 | private readonly string _token; 13 | 14 | public ServerTypeClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | public async Task> Get() 20 | { 21 | List listServerType = new List(); 22 | long page = 0; 23 | while (true) 24 | { 25 | // Nex 26 | page++; 27 | 28 | // Get list 29 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/server_types?page={page}&per_page={Core.PerPage}")) ?? new Response(); 30 | 31 | // Run 32 | foreach (ServerType row in response.ServerTypes) 33 | { 34 | listServerType.Add(row); 35 | } 36 | 37 | // Finish? 38 | if (response.Meta.Pagination.NextPage == 0) 39 | { 40 | // Yes, finish 41 | return listServerType; 42 | } 43 | } 44 | } 45 | 46 | public async Task Get(long id) 47 | { 48 | // Get list 49 | string json = await Core.SendGetRequest(_token, $"/server_types/{id}"); 50 | 51 | // Set 52 | JObject result = JObject.Parse(json); 53 | ServerType serverType = JsonConvert.DeserializeObject($"{result["server_type"]}") ?? new ServerType(); 54 | 55 | // Return 56 | return serverType; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/SshKeyClient.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Volume; 2 | using Newtonsoft.Json.Linq; 3 | using Newtonsoft.Json; 4 | using System.Collections.Generic; 5 | using System.Threading.Tasks; 6 | using HetznerCloudApi.Object.SshKey; 7 | using HetznerCloudApi.Object.SshKey.Get; 8 | 9 | namespace HetznerCloudApi.Client 10 | { 11 | public class SshKeyClient 12 | { 13 | private readonly string _token; 14 | 15 | public SshKeyClient(string token) 16 | { 17 | _token = token; 18 | } 19 | 20 | /// 21 | /// Returns all SSH key objects. 22 | /// 23 | /// 24 | public async Task> Get() 25 | { 26 | List list = new List(); 27 | long page = 0; 28 | while (true) 29 | { 30 | // Nex 31 | page++; 32 | 33 | // Get list 34 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/ssh_keys?page={page}&per_page={Core.PerPage}")) ?? new Response(); 35 | 36 | // Run 37 | foreach (SshKey row in response.SshKeys) 38 | { 39 | list.Add(row); 40 | } 41 | 42 | // Finish? 43 | if (response.Meta.Pagination.NextPage == 0) 44 | { 45 | // Yes, finish 46 | return list; 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// Returns a specific SSH key object. 53 | /// 54 | /// ID of the SSH key 55 | /// 56 | public async Task Get(long id) 57 | { 58 | // Get list 59 | string json = await Core.SendGetRequest(_token, $"/ssh_keys/{id}"); 60 | 61 | // Set 62 | JObject result = JObject.Parse(json); 63 | SshKey sshKey = JsonConvert.DeserializeObject($"{result["ssh_key"]}") ?? new SshKey(); 64 | 65 | // Return 66 | return sshKey; 67 | } 68 | 69 | /// 70 | /// Creates a new SSH key with the given name and public_key. Once an SSH key is created, it can be used in other calls such as creating Servers. 71 | /// 72 | /// Name of the SSH key 73 | /// Public key 74 | /// 75 | public async Task Create(string name, string publicKey) 76 | { 77 | // Preparing raw 78 | string raw = $"{{ \"name\": \"{name}\", \"public_key\": \"{publicKey}\" }}"; 79 | 80 | // Send post 81 | string jsonResponse = await Core.SendPostRequest(_token, "/ssh_keys", raw); 82 | 83 | // Return 84 | JObject result = JObject.Parse(jsonResponse); 85 | return JsonConvert.DeserializeObject($"{result["ssh_key"]}") ?? new SshKey(); 86 | } 87 | 88 | /// 89 | /// Updates an SSH key. You can update an SSH key name and an SSH key labels. 90 | /// 91 | /// the SSH 92 | /// 93 | public async Task Update(SshKey sshKey) 94 | { 95 | // Preparing raw 96 | string raw = $"{{ \"name\": \"{sshKey.Name}\" }}"; 97 | 98 | // Send post 99 | string jsonResponse = await Core.SendPutRequest(_token, $"/ssh_keys/{sshKey.Id}", raw); 100 | 101 | // Return 102 | JObject result = JObject.Parse(jsonResponse); 103 | return JsonConvert.DeserializeObject($"{result["ssh_key"]}") ?? new SshKey(); 104 | } 105 | 106 | /// 107 | /// Deletes an SSH key. It cannot be used anymore. 108 | /// 109 | /// 110 | /// 111 | public async Task Delete(long id) 112 | { 113 | await Core.SendDeleteRequest(_token, $"/ssh_keys/{id}"); 114 | } 115 | 116 | /// 117 | /// Deletes an SSH key. It cannot be used anymore. 118 | /// 119 | /// 120 | /// 121 | public async Task Delete(SshKey sshKey) 122 | { 123 | await Delete(sshKey.Id); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/VolumeActionClient.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using HetznerCloudApi.Object.Action; 5 | using Newtonsoft.Json.Linq; 6 | using HetznerCloudApi.Object.Action.Get; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class VolumeActionClient 11 | { 12 | private readonly string _token; 13 | 14 | public VolumeActionClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Get all Actions for a Volume 21 | /// 22 | /// ID of the Volume 23 | /// 24 | public async Task> GetAllActions(long volumeId) 25 | { 26 | List list = new List(); 27 | long page = 0; 28 | while (true) 29 | { 30 | // Nex 31 | page++; 32 | 33 | // Get list 34 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/volumes/{volumeId}/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 35 | 36 | // Run 37 | foreach (Action row in response.Actions) 38 | { 39 | list.Add(row); 40 | } 41 | 42 | // Finish? 43 | if (response.Meta.Pagination.NextPage == 0) 44 | { 45 | // Yes, finish 46 | return list; 47 | } 48 | } 49 | } 50 | 51 | /// 52 | /// Get an Action for a Volume 53 | /// 54 | /// ID of the Volume 55 | /// ID of the Action 56 | /// 57 | public async Task GetAction(long volumeId, long actionId) 58 | { 59 | // Get list 60 | string json = await Core.SendGetRequest(_token, $"/volumes/{volumeId}/actions/{actionId}"); 61 | 62 | // Set 63 | JObject result = JObject.Parse(json); 64 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 65 | 66 | // Return 67 | return action; 68 | } 69 | 70 | /// 71 | /// Attaches a Volume to a Server. Works only if the Server is in the same Location as the Volume. 72 | /// 73 | /// ID of the Volume 74 | /// ID of the Server the Volume will be attached to 75 | /// Auto-mount the Volume after attaching it 76 | /// 77 | public async Task Attach(long volumeId, long serverId, bool automount = true) 78 | { 79 | // Preparing raw 80 | string raw = $"{{ \"automount\": {(automount ? "true" : "false")}, \"server\": {serverId} }}"; 81 | 82 | // Send post 83 | string jsonResponse = await Core.SendPostRequest(_token, $"/volumes/{volumeId}/actions/attach", raw); 84 | 85 | // Return 86 | JObject result = JObject.Parse(jsonResponse); 87 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 88 | } 89 | 90 | /// 91 | /// Detaches a Volume from the Server it’s attached to. You may attach it to a Server again at a later time. 92 | /// 93 | /// 94 | /// 95 | public async Task Detach(long volumeId) 96 | { 97 | // Send post 98 | string jsonResponse = await Core.SendPostRequest(_token, $"/volumes/{volumeId}/actions/detach"); 99 | 100 | // Return 101 | JObject result = JObject.Parse(jsonResponse); 102 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 103 | } 104 | 105 | /// 106 | /// Changes the protection configuration of a Volume. 107 | /// 108 | /// ID of the Volume 109 | /// If true, prevents the Volume from being deleted 110 | /// 111 | public async Task ChangeProtection(long volumeId, bool protection) 112 | { 113 | // Preparing raw 114 | string raw = $"{{ \"delete\": {(protection ? "true" : "false")} }}"; 115 | 116 | // Send post 117 | string jsonResponse = await Core.SendPostRequest(_token, $"/volumes/{volumeId}/actions/change_protection", raw); 118 | 119 | // Return 120 | JObject result = JObject.Parse(jsonResponse); 121 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 122 | } 123 | 124 | /// 125 | /// Changes the size of a Volume. Note that downsizing a Volume is not possible. 126 | /// 127 | /// 128 | /// 129 | /// 130 | public async Task Resize(long volumeId, long size) 131 | { 132 | // Preparing raw 133 | string raw = $"{{ \"size\": {size} }}"; 134 | 135 | // Send post 136 | string jsonResponse = await Core.SendPostRequest(_token, $"/volumes/{volumeId}/actions/resize", raw); 137 | 138 | // Return 139 | JObject result = JObject.Parse(jsonResponse); 140 | return JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 141 | } 142 | 143 | /// 144 | /// Returns all Action objects 145 | /// 146 | /// 147 | public async Task> GetAllActions() 148 | { 149 | List list = new List(); 150 | long page = 0; 151 | while (true) 152 | { 153 | // Nex 154 | page++; 155 | 156 | // Get list 157 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/volumes/actions?page={page}&per_page={Core.PerPage}")) ?? new Response(); 158 | 159 | // Run 160 | foreach (Action row in response.Actions) 161 | { 162 | list.Add(row); 163 | } 164 | 165 | // Finish? 166 | if (response.Meta.Pagination.NextPage == 0) 167 | { 168 | // Yes, finish 169 | return list; 170 | } 171 | } 172 | } 173 | 174 | /// 175 | /// Returns a specific Action object 176 | /// 177 | /// ID of the Resource 178 | /// 179 | public async Task GetAction(long actionId) 180 | { 181 | // Get list 182 | string json = await Core.SendGetRequest(_token, $"/volumes/actions/{actionId}"); 183 | 184 | // Set 185 | JObject result = JObject.Parse(json); 186 | Action action = JsonConvert.DeserializeObject($"{result["action"]}") ?? new Action(); 187 | 188 | // Return 189 | return action; 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /HetznerCloudApi/Client/VolumeClient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json.Linq; 3 | using Newtonsoft.Json; 4 | using System.Threading.Tasks; 5 | using HetznerCloudApi.Object.Volume; 6 | using HetznerCloudApi.Object.Volume.Get; 7 | 8 | namespace HetznerCloudApi.Client 9 | { 10 | public class VolumeClient 11 | { 12 | private readonly string _token; 13 | 14 | public VolumeClient(string token) 15 | { 16 | _token = token; 17 | } 18 | 19 | /// 20 | /// Gets all existing Volumes that you have available 21 | /// 22 | /// 23 | public async Task> Get() 24 | { 25 | List list = new List(); 26 | long page = 0; 27 | while (true) 28 | { 29 | // Nex 30 | page++; 31 | 32 | // Get list 33 | Response response = JsonConvert.DeserializeObject(await Core.SendGetRequest(_token, $"/volumes?page={page}&per_page={Core.PerPage}")) ?? new Response(); 34 | 35 | // Run 36 | foreach (Volume row in response.Volumes) 37 | { 38 | list.Add(row); 39 | } 40 | 41 | // Finish? 42 | if (response.Meta.Pagination.NextPage == 0) 43 | { 44 | // Yes, finish 45 | return list; 46 | } 47 | } 48 | } 49 | 50 | /// 51 | /// Gets a specific Volume object 52 | /// 53 | /// 54 | /// 55 | public async Task Get(long id) 56 | { 57 | // Get list 58 | string json = await Core.SendGetRequest(_token, $"/volumes/{id}"); 59 | 60 | // Set 61 | JObject result = JObject.Parse(json); 62 | Volume volume = JsonConvert.DeserializeObject($"{result["volume"]}") ?? new Volume(); 63 | 64 | // Return 65 | return volume; 66 | } 67 | 68 | /// 69 | /// Create a Volume 70 | /// 71 | /// Name of the volume 72 | /// Size of the Volume in GB 73 | /// Filesystem of the Volume if formatted on creation, null if not formatted on creation 74 | /// Location to create the Volume 75 | /// 76 | public async Task Create(string name, long size, VolumeFormat volumeFormat, long locationId) 77 | { 78 | // Preparing raw 79 | string raw = $"{{\"automount\":false,\"format\":\"{volumeFormat}\",\"location\":{locationId},\"name\":\"{name}\",\"size\":{size}}}"; 80 | 81 | // Send post 82 | string jsonResponse = await Core.SendPostRequest(_token, "/volumes", raw); 83 | 84 | // Return 85 | JObject result = JObject.Parse(jsonResponse); 86 | return JsonConvert.DeserializeObject($"{result["volume"]}") ?? new Volume(); 87 | } 88 | 89 | /// 90 | /// Updates the Volume properties 91 | /// 92 | /// 93 | /// 94 | public async Task Update(Volume volume) 95 | { 96 | // Preparing raw 97 | string raw = $"{{\"name\":\"{volume.Name}\"}}"; 98 | 99 | // Send post 100 | string jsonResponse = await Core.SendPutRequest(_token, $"/volumes/{volume.Id}", raw); 101 | 102 | // Return 103 | JObject result = JObject.Parse(jsonResponse); 104 | return JsonConvert.DeserializeObject($"{result["volume"]}") ?? new Volume(); 105 | } 106 | 107 | /// 108 | /// Deletes a volume. All Volume data is irreversibly destroyed. The Volume must not be attached to a Server and it must not have delete protection enabled. 109 | /// 110 | /// 111 | /// 112 | public async Task Delete(long id) 113 | { 114 | // Send post 115 | await Core.SendDeleteRequest(_token, $"/volumes/{id}"); 116 | } 117 | 118 | /// 119 | /// Deletes a volume. All Volume data is irreversibly destroyed. The Volume must not be attached to a Server and it must not have delete protection enabled. 120 | /// 121 | /// 122 | /// 123 | public async Task Delete(Volume volume) 124 | { 125 | // Send post 126 | await Delete(volume.Id); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /HetznerCloudApi/Core.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using System; 5 | using HetznerCloudApi.Object.Universal; 6 | using Newtonsoft.Json.Linq; 7 | using Newtonsoft.Json; 8 | using System.Net.Http.Headers; 9 | 10 | namespace HetznerCloudApi 11 | { 12 | public class Core 13 | { 14 | public static long PerPage = 50; 15 | 16 | private const string ApiServer = "https://api.hetzner.cloud/v1"; 17 | 18 | public static async Task SendGetRequest(string token, string url) 19 | { 20 | HttpResponseMessage httpResponseMessage; 21 | using (HttpClient httpClient = new HttpClient()) 22 | { 23 | using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("GET"), $"{ApiServer}{url}")) 24 | { 25 | httpRequestMessage.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); 26 | httpResponseMessage = await httpClient.SendAsync(httpRequestMessage); 27 | } 28 | } 29 | 30 | // Response 31 | string json = await httpResponseMessage.Content.ReadAsStringAsync(); 32 | 33 | switch (httpResponseMessage.StatusCode) 34 | { 35 | case HttpStatusCode.OK: 36 | break; 37 | 38 | default: 39 | // Get Error 40 | JObject result = JObject.Parse(json); 41 | Error error = JsonConvert.DeserializeObject($"{result["error"]}") ?? new Error(); 42 | 43 | //Check error 44 | if (error.Message.Contains("with ID") && error.Message.Contains("not found")) 45 | { 46 | // The error is due to the resource not being found. Let's make it return empty instead of an error. 47 | json = "{}"; 48 | } 49 | else 50 | { 51 | // If it's a genuine error 52 | throw new Exception($"{error.Code} - {error.Message}"); 53 | } 54 | break; 55 | } 56 | 57 | return json; 58 | } 59 | 60 | public static async Task SendPostRequest(string token, string url, string content) 61 | { 62 | HttpResponseMessage httpResponseMessage; 63 | using (HttpClient httpClient = new HttpClient()) 64 | { 65 | using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("POST"), $"{ApiServer}{url}")) 66 | { 67 | httpRequestMessage.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); 68 | httpRequestMessage.Content = new StringContent(content); 69 | httpRequestMessage.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); 70 | httpResponseMessage = await httpClient.SendAsync(httpRequestMessage); 71 | } 72 | } 73 | 74 | // Response 75 | string json = await httpResponseMessage.Content.ReadAsStringAsync(); 76 | 77 | switch (httpResponseMessage.StatusCode) 78 | { 79 | case HttpStatusCode.Created: 80 | break; 81 | 82 | default: 83 | // Get Error 84 | JObject result = JObject.Parse(json); 85 | Error error = JsonConvert.DeserializeObject($"{result["error"]}") ?? new Error(); 86 | 87 | //Check error 88 | if (error.Message.Contains("with ID") && error.Message.Contains("not found")) 89 | { 90 | // The error is due to the resource not being found. Let's make it return empty instead of an error. 91 | json = "{}"; 92 | } 93 | else 94 | { 95 | // If it's a genuine error 96 | throw new Exception($"{error.Code} - {error.Message}"); 97 | } 98 | break; 99 | } 100 | 101 | return json; 102 | } 103 | 104 | public static async Task SendPostRequest(string token, string url) 105 | { 106 | HttpResponseMessage httpResponseMessage; 107 | using (HttpClient httpClient = new HttpClient()) 108 | { 109 | using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("POST"), $"{ApiServer}{url}")) 110 | { 111 | httpRequestMessage.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); 112 | httpResponseMessage = await httpClient.SendAsync(httpRequestMessage); 113 | } 114 | } 115 | 116 | // Response 117 | string json = await httpResponseMessage.Content.ReadAsStringAsync(); 118 | 119 | switch (httpResponseMessage.StatusCode) 120 | { 121 | case HttpStatusCode.Created: 122 | break; 123 | 124 | default: 125 | // Get Error 126 | JObject result = JObject.Parse(json); 127 | Error error = JsonConvert.DeserializeObject($"{result["error"]}") ?? new Error(); 128 | 129 | //Check error 130 | if (error.Message.Contains("with ID") && error.Message.Contains("not found")) 131 | { 132 | // The error is due to the resource not being found. Let's make it return empty instead of an error. 133 | json = "{}"; 134 | } 135 | else 136 | { 137 | // If it's a genuine error 138 | throw new Exception($"{error.Code} - {error.Message}"); 139 | } 140 | break; 141 | } 142 | 143 | return json; 144 | } 145 | 146 | public static async Task SendPutRequest(string token, string url, string content) 147 | { 148 | HttpResponseMessage httpResponseMessage; 149 | using (HttpClient httpClient = new HttpClient()) 150 | { 151 | using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod("PUT"), $"{ApiServer}{url}")) 152 | { 153 | httpRequestMessage.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); 154 | httpRequestMessage.Content = new StringContent(content); 155 | httpRequestMessage.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); 156 | httpResponseMessage = await httpClient.SendAsync(httpRequestMessage); 157 | } 158 | } 159 | 160 | // Response 161 | string json = await httpResponseMessage.Content.ReadAsStringAsync(); 162 | 163 | switch (httpResponseMessage.StatusCode) 164 | { 165 | case HttpStatusCode.OK: 166 | break; 167 | 168 | default: 169 | // Get Error 170 | JObject result = JObject.Parse(json); 171 | Error error = JsonConvert.DeserializeObject($"{result["error"]}") ?? new Error(); 172 | 173 | //Check error 174 | if (error.Message.Contains("with ID") && error.Message.Contains("not found")) 175 | { 176 | // The error is due to the resource not being found. Let's make it return empty instead of an error. 177 | json = "{}"; 178 | } 179 | else 180 | { 181 | // If it's a genuine error 182 | throw new Exception($"{error.Code} - {error.Message}"); 183 | } 184 | break; 185 | } 186 | 187 | return json; 188 | } 189 | 190 | public static async Task SendDeleteRequest(string token, string url) 191 | { 192 | HttpResponseMessage httpResponseMessage; 193 | using (var httpClient = new HttpClient()) 194 | { 195 | using (var request = new HttpRequestMessage(new HttpMethod("DELETE"), $"{ApiServer}{url}")) 196 | { 197 | request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); 198 | httpResponseMessage = await httpClient.SendAsync(request); 199 | } 200 | } 201 | 202 | // Response 203 | string json = await httpResponseMessage.Content.ReadAsStringAsync(); 204 | 205 | switch (httpResponseMessage.StatusCode) 206 | { 207 | case HttpStatusCode.NoContent: 208 | case HttpStatusCode.OK: 209 | break; 210 | 211 | default: 212 | JObject result = JObject.Parse(json); 213 | Error error = JsonConvert.DeserializeObject($"{result["error"]}") ?? new Error(); 214 | throw new Exception($"{error.Code} - {error.Message}"); 215 | } 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /HetznerCloudApi/HetznerCloudApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | True 6 | 7 | HetznerCloud.API 8 | HetznerCloud.API 9 | 1.1.9 10 | ljchuello 11 | This C# / .NET Core SDK simplifies interaction with the powerful Hetzner Cloud API, enabling efficient management of resources such as servers, firewalls, networks, SSH keys, and volumes. Optimized for web developers and .NET applications, it streamlines cloud operations, providing the necessary control over your resources in Hetzner Cloud. 12 | https://www.nuget.org/packages/HetznerCloud.API 13 | https://github.com/ljchuello/HetznerCloud.API 14 | git 15 | MIT 16 | C#;Hetzner;Hetzner Cloud;Hetzner API; LJChuello 17 | icon-circle-cloud.png 18 | README.md 19 | 20 | 21 | 22 | 23 | True 24 | \ 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | True 35 | \ 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /HetznerCloudApi/HetznerCloudClient.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Client; 2 | using HetznerCloudApi.Object.Server; 3 | 4 | namespace HetznerCloudApi 5 | { 6 | public class HetznerCloudClient 7 | { 8 | public string Token { get; private set; } 9 | 10 | public HetznerCloudClient(string token) 11 | { 12 | Token = token; 13 | 14 | Action = new ActionClient(token); 15 | Datacenter = new DatacenterClient(token); 16 | Firewall = new FirewallClient(token); 17 | FirewallAction = new FirewallActionClient(token); 18 | Image = new ImageClient(token); 19 | Location = new LocationClient(token); 20 | Network = new NetworkClient(token); 21 | NetworkAction = new NetworkActionClient(token); 22 | Network = new NetworkClient(token); 23 | Server = new ServerClient(token); 24 | ServerType = new ServerTypeClient(token); 25 | SshKey = new SshKeyClient(token); 26 | Volume = new VolumeClient(token); 27 | VolumeAction = new VolumeActionClient(token); 28 | } 29 | 30 | public ActionClient Action { get; private set; } 31 | public DatacenterClient Datacenter { get; private set; } 32 | public FirewallClient Firewall { get; private set; } 33 | public FirewallActionClient FirewallAction { get; private set; } 34 | public ImageClient Image { get; private set; } 35 | public LocationClient Location { get; private set; } 36 | public NetworkClient Network { get; private set; } 37 | public NetworkActionClient NetworkAction { get; private set; } 38 | public ServerClient Server { get; private set; } 39 | public ServerTypeClient ServerType { get; private set; } 40 | public SshKeyClient SshKey { get; private set; } 41 | public VolumeClient Volume { get; private set; } 42 | public VolumeActionClient VolumeAction { get; private set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Action/Action.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace HetznerCloudApi.Object.Action 6 | { 7 | public class Action 8 | { 9 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 10 | public long Id { get; set; } = 0; 11 | 12 | [JsonProperty("command", NullValueHandling = NullValueHandling.Ignore)] 13 | public string Command { get; set; } = string.Empty; 14 | 15 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 16 | public string Status { get; set; } = string.Empty; 17 | 18 | [JsonProperty("progress", NullValueHandling = NullValueHandling.Ignore)] 19 | public long Progress { get; set; } = 0; 20 | 21 | [JsonProperty("started", NullValueHandling = NullValueHandling.Ignore)] 22 | public DateTime Started { get; set; } = new DateTime(1900, 01, 01); 23 | 24 | [JsonProperty("finished", NullValueHandling = NullValueHandling.Ignore)] 25 | public DateTime Finished { get; set; } = new DateTime(1900, 01, 01); 26 | 27 | [JsonProperty("resources", NullValueHandling = NullValueHandling.Ignore)] 28 | public List Resources { get; set; } = new List(); 29 | 30 | //[JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)] 31 | //public Error Error { get; set; } = new Error(); 32 | } 33 | 34 | public class Resource 35 | { 36 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 37 | public long Id { get; set; } = 0; 38 | 39 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 40 | public string Type { get; set; } = string.Empty; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Action/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.Action.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("actions", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Actions { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Datacenter/Datacenter.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace HetznerCloudApi.Object.Datacenter 5 | { 6 | public class Datacenter 7 | { 8 | /// 9 | /// Description of the Datacenter 10 | /// 11 | [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] 12 | public string Description { get; set; } = string.Empty; 13 | 14 | /// 15 | /// ID of the Resource 16 | /// 17 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 18 | public long Id { get; set; } = 0; 19 | 20 | /// 21 | /// Location 22 | /// 23 | [JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)] 24 | public Location.Location Location { get; set; } = new Location.Location(); 25 | 26 | /// 27 | /// Unique identifier of the Datacenter 28 | /// 29 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 30 | public string Name { get; set; } = string.Empty; 31 | 32 | /// 33 | /// The Server types the Datacenter can handle 34 | /// 35 | [JsonProperty("server_types", NullValueHandling = NullValueHandling.Ignore)] 36 | public ServerTypes ServerTypes { get; set; } = new ServerTypes(); 37 | } 38 | 39 | public class ServerTypes 40 | { 41 | [JsonProperty("available", NullValueHandling = NullValueHandling.Ignore)] 42 | public List Available { get; set; } = new List(); 43 | 44 | [JsonProperty("available_for_migration", NullValueHandling = NullValueHandling.Ignore)] 45 | public List AvailableForMigration { get; set; } = new List(); 46 | 47 | [JsonProperty("supported", NullValueHandling = NullValueHandling.Ignore)] 48 | public List Supported { get; set; } = new List(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Datacenter/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using HetznerCloudApi.Object.Universal; 3 | using Newtonsoft.Json; 4 | 5 | namespace HetznerCloudApi.Object.Datacenter.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("datacenters", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Datacenters { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Firewall/Firewall.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System; 4 | using Newtonsoft.Json.Converters; 5 | 6 | namespace HetznerCloudApi.Object.Firewall 7 | { 8 | public class Firewall 9 | { 10 | /// 11 | /// ID of the Resource 12 | /// 13 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 14 | public long Id { get; set; } = 0; 15 | 16 | /// 17 | /// Name of the Resource. Must be unique per Project. 18 | /// 19 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 20 | public string Name { get; set; } = string.Empty; 21 | 22 | //[JsonProperty("labels", NullValueHandling = NullValueHandling.Ignore)] 23 | //public Labels Labels { get; set; } 24 | 25 | /// 26 | /// Point in time when the Resource was created 27 | /// 28 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 29 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 30 | 31 | [JsonProperty("rules", NullValueHandling = NullValueHandling.Ignore)] 32 | public List Rules { get; set; } = new List(); 33 | 34 | [JsonProperty("applied_to", NullValueHandling = NullValueHandling.Ignore)] 35 | public List AppliedTo { get; set; } = new List(); 36 | } 37 | 38 | public class Rule 39 | { 40 | /// 41 | /// Possible enum values: 42 | /// inout 43 | /// Select traffic direction on which rule should be applied. Use source_ips for direction in and destination_ips for direction out 44 | /// 45 | [JsonProperty("direction", NullValueHandling = NullValueHandling.Ignore)] 46 | [JsonConverter(typeof(StringEnumConverter))] 47 | public Direction Direction { get; set; } = Direction.@in; 48 | 49 | /// 50 | /// Possible enum values: 51 | /// tcpudpicmpespgre 52 | /// Type of traffic to allow 53 | /// 54 | [JsonProperty("protocol", NullValueHandling = NullValueHandling.Ignore)] 55 | [JsonConverter(typeof(StringEnumConverter))] 56 | public Protocol Protocol { get; set; } = Protocol.tcp; 57 | 58 | /// 59 | /// Port or port range to which traffic will be allowed, only applicable for protocols TCP and UDP. A port range can be specified by separating two ports with a dash, e.g 1024-5000. 60 | /// 61 | [JsonProperty("port", NullValueHandling = NullValueHandling.Ignore)] 62 | public string Port { get; set; } = string.Empty; 63 | 64 | /// 65 | /// List of permitted IPv4/IPv6 addresses in CIDR notation. Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses. You can specify 100 CIDRs at most. 66 | /// 67 | [JsonProperty("source_ips", NullValueHandling = NullValueHandling.Ignore)] 68 | public List SourceIps { get; set; } = new List(); 69 | 70 | /// 71 | /// List of permitted IPv4/IPv6 addresses in CIDR notation. Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses. You can specify 100 CIDRs at most. 72 | /// 73 | [JsonProperty("destination_ips", NullValueHandling = NullValueHandling.Ignore)] 74 | public List DestinationIps { get; set; } = new List(); 75 | 76 | /// 77 | /// Description of the Rule 78 | /// 79 | [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] 80 | public string Description { get; set; } = string.Empty; 81 | } 82 | 83 | public class AppliedTo 84 | { 85 | /// 86 | /// Type of resource referenced 87 | /// 88 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 89 | public string Type { get; set; } = string.Empty; 90 | 91 | [JsonProperty("server", NullValueHandling = NullValueHandling.Ignore)] 92 | public Server Server { get; set; } = new Server(); 93 | } 94 | 95 | public class Server 96 | { 97 | /// 98 | /// ID of the Resource 99 | /// 100 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 101 | public long Id { get; set; } = 0; 102 | } 103 | 104 | public enum Direction 105 | { 106 | @in, 107 | @out, 108 | } 109 | 110 | public enum Protocol 111 | { 112 | tcp, 113 | udp, 114 | icmp, 115 | esp, 116 | gre, 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Firewall/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.Firewall.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("firewalls", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Firewalls { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Image/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using HetznerCloudApi.Object.Universal; 3 | using Newtonsoft.Json; 4 | 5 | namespace HetznerCloudApi.Object.Image.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("images", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Images { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Image/Image.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace HetznerCloudApi.Object.Image 5 | { 6 | public class Image 7 | { 8 | /// 9 | /// ID of the Image 10 | /// 11 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 12 | public long Id { get; set; } = 0; 13 | 14 | /// 15 | /// Type of the Image 16 | /// 17 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 18 | public string Type { get; set; } = string.Empty; 19 | 20 | /// 21 | /// Whether the Image can be used or if it's still being created or unavailable 22 | /// 23 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 24 | public string Status { get; set; } = string.Empty; 25 | 26 | /// 27 | /// Unique identifier of the Image. This value is only set for system Images. 28 | /// 29 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 30 | public string Name { get; set; } = string.Empty; 31 | 32 | /// 33 | /// Description of the Image 34 | /// 35 | [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] 36 | public string Description { get; set; } = string.Empty; 37 | 38 | //[JsonProperty("image_size")] 39 | //public object ImageSize { get; set; } 40 | 41 | /// 42 | /// Size of the disk contained in the Image in GB 43 | /// 44 | [JsonProperty("disk_size", NullValueHandling = NullValueHandling.Ignore)] 45 | public long DiskSize { get; set; } = 0; 46 | 47 | /// 48 | /// Point in time when the Resource was created 49 | /// 50 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 51 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 52 | 53 | //[JsonProperty("created_from")] 54 | //public object CreatedFrom { get; set; } 55 | 56 | //[JsonProperty("bound_to")] 57 | //public object BoundTo { get; set; } 58 | 59 | /// 60 | /// Flavor of operating system contained in the Image 61 | /// 62 | [JsonProperty("os_flavor", NullValueHandling = NullValueHandling.Ignore)] 63 | public string OsFlavor { get; set; } = string.Empty; 64 | 65 | /// 66 | /// Operating system version 67 | /// 68 | [JsonProperty("os_version", NullValueHandling = NullValueHandling.Ignore)] 69 | public string OsVersion { get; set; } = string.Empty; 70 | 71 | /// 72 | /// Indicates that rapid deploy of the Image is available 73 | /// 74 | [JsonProperty("rapid_deploy", NullValueHandling = NullValueHandling.Ignore)] 75 | public bool RapidDeploy { get; set; } = false; 76 | 77 | //[JsonProperty("protection")] 78 | //public Protection Protection { get; set; } 79 | 80 | //[JsonProperty("deprecated")] 81 | //public object Deprecated { get; set; } 82 | 83 | //[JsonProperty("labels")] 84 | //public Labels Labels { get; set; } 85 | 86 | //[JsonProperty("deleted")] 87 | //public object Deleted { get; set; } 88 | 89 | /// 90 | /// Type of cpu architecture this image is compatible with. 91 | /// 92 | [JsonProperty("architecture", NullValueHandling = NullValueHandling.Ignore)] 93 | public string Architecture { get; set; } = string.Empty; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Location/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using HetznerCloudApi.Object.Universal; 3 | using Newtonsoft.Json; 4 | 5 | namespace HetznerCloudApi.Object.Location.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("locations", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Locations { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Location/Location.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace HetznerCloudApi.Object.Location 4 | { 5 | public class Location 6 | { 7 | /// 8 | /// City the Location is closest to 9 | /// 10 | [JsonProperty("city", NullValueHandling = NullValueHandling.Ignore)] 11 | public string City { get; set; } = string.Empty; 12 | 13 | /// 14 | /// ISO 3166-1 alpha-2 code of the country the Location resides in 15 | /// 16 | [JsonProperty("country", NullValueHandling = NullValueHandling.Ignore)] 17 | public string Country { get; set; } = string.Empty; 18 | 19 | /// 20 | /// Description of the Location 21 | /// 22 | [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] 23 | public string Description { get; set; } = string.Empty; 24 | 25 | /// 26 | /// ID of the Location 27 | /// 28 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 29 | public long Id { get; set; } = 0; 30 | 31 | /// 32 | /// Latitude of the city closest to the Location 33 | /// 34 | [JsonProperty("latitude", NullValueHandling = NullValueHandling.Ignore)] 35 | public double Latitude { get; set; } = 0; 36 | 37 | /// 38 | /// Longitude of the city closest to the Location 39 | /// 40 | [JsonProperty("longitude", NullValueHandling = NullValueHandling.Ignore)] 41 | public double Longitude { get; set; }= 0; 42 | 43 | /// 44 | /// Unique identifier of the Location 45 | /// 46 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 47 | public string Name { get; set; } = string.Empty; 48 | 49 | /// 50 | /// Name of network zone this Location resides in 51 | /// 52 | [JsonProperty("network_zone", NullValueHandling = NullValueHandling.Ignore)] 53 | public string NetworkZone { get; set; } = string.Empty; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Network/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.Network.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("networks", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Networks { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Network/Network.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | namespace HetznerCloudApi.Object.Network 7 | { 8 | public class Network 9 | { 10 | /// 11 | /// ID of the Network 12 | /// 13 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 14 | public long Id { get; set; } = 0; 15 | 16 | /// 17 | /// Name of the Network 18 | /// 19 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 20 | public string Name { get; set; } = string.Empty; 21 | 22 | /// 23 | /// IPv4 prefix of the whole Network 24 | /// 25 | [JsonProperty("ip_range", NullValueHandling = NullValueHandling.Ignore)] 26 | public string IpRange { get; set; } = string.Empty; 27 | 28 | /// 29 | /// Array subnets allocated in this Network 30 | /// 31 | [JsonProperty("subnets", NullValueHandling = NullValueHandling.Ignore)] 32 | public List Subnets { get; set; } = new List(); 33 | 34 | /// 35 | /// Array of routes set in this Network 36 | /// 37 | [JsonProperty("routes", NullValueHandling = NullValueHandling.Ignore)] 38 | public List Routes { get; set; } = new List(); 39 | 40 | /// 41 | /// Array of IDs of Servers attached to this Network 42 | /// 43 | [JsonProperty("servers", NullValueHandling = NullValueHandling.Ignore)] 44 | public List Servers { get; set; } = new List(); 45 | 46 | /// 47 | /// Array of IDs of Load Balancers attached to this Network 48 | /// 49 | [JsonProperty("load_balancers", NullValueHandling = NullValueHandling.Ignore)] 50 | public List LoadBalancers { get; set; } = new List(); 51 | 52 | /// 53 | /// Protection configuration for the Network 54 | /// 55 | [JsonProperty("protection", NullValueHandling = NullValueHandling.Ignore)] 56 | public Protection Protection { get; set; } = new Protection(); 57 | 58 | //[JsonProperty("labels", NullValueHandling = NullValueHandling.Ignore)] 59 | //public Labels Labels { get; set; } 60 | 61 | /// 62 | /// Point in time when the Network was created 63 | /// 64 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 65 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 66 | 67 | /// 68 | /// Indicates if the routes from this network should be exposed to the vSwitch connection. 69 | /// 70 | [JsonProperty("expose_routes_to_vswitch", NullValueHandling = NullValueHandling.Ignore)] 71 | public bool ExposeRoutesToVswitch { get; set; } = false; 72 | } 73 | 74 | public class Route 75 | { 76 | /// 77 | /// Destination network or host of this route. Must not overlap with an existing ip_range in any subnets or with any destinations in other routes or with the first IP of the networks ip_range or with 172.31.1.1. Must be one of the private IPv4 ranges of RFC1918. 78 | /// 79 | [JsonProperty("destination", NullValueHandling = NullValueHandling.Ignore)] 80 | public string Destination { get; set; } = string.Empty; 81 | 82 | /// 83 | /// Gateway for the route. Cannot be the first IP of the networks ip_range and also cannot be 172.31.1.1 as this IP is being used as a gateway for the public network interface of Servers. 84 | /// 85 | [JsonProperty("gateway", NullValueHandling = NullValueHandling.Ignore)] 86 | public string Gateway { get; set; } = string.Empty; 87 | } 88 | 89 | public class Subnet 90 | { 91 | /// 92 | /// Type of Subnetwork 93 | /// 94 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 95 | public string Type { get; set; } = string.Empty; 96 | 97 | /// 98 | /// Range to allocate IPs from. Must be a Subnet of the ip_range of the parent network object and must not overlap with any other subnets or with any destinations in routes. Minimum Network size is /30. We suggest that you pick a bigger Network with a /24 netmask. 99 | /// 100 | [JsonProperty("ip_range", NullValueHandling = NullValueHandling.Ignore)] 101 | public string IpRange { get; set; } = string.Empty; 102 | 103 | /// 104 | /// Name of Network zone. The Location object contains the network_zone property each Location belongs to. 105 | /// 106 | [JsonProperty("network_zone", NullValueHandling = NullValueHandling.Ignore)] 107 | public string NetworkZone { get; set; } = string.Empty; 108 | 109 | //[JsonProperty("vswitch_id", NullValueHandling = NullValueHandling.Ignore)] 110 | //public object VswitchId { get; set; } 111 | 112 | /// 113 | /// Gateway for Servers attached to this subnet. For subnets of type Server this is always the first IP of the network IP range. 114 | /// 115 | [JsonProperty("gateway", NullValueHandling = NullValueHandling.Ignore)] 116 | public string Gateway { get; set; } = string.Empty; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/PlacementGroup/PlacementGroup.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace HetznerCloudApi.Object.PlacementGroup 6 | { 7 | public class PlacementGroup 8 | { 9 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 10 | public long Id { get; set; } = 0; 11 | 12 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 13 | public string Name { get; set; } = string.Empty; 14 | 15 | //[JsonProperty("labels", NullValueHandling = NullValueHandling.Ignore)] 16 | //public Labels Labels { get; set; } 17 | 18 | [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] 19 | public string Type { get; set; } = string.Empty; 20 | 21 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 22 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 23 | 24 | [JsonProperty("servers", NullValueHandling = NullValueHandling.Ignore)] 25 | public List Servers { get; set; } = new List(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Server/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.Server.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("servers", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Servers { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Server/Server.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | namespace HetznerCloudApi.Object.Server 7 | { 8 | public class Server 9 | { 10 | /// 11 | /// ID of the Resource 12 | /// 13 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 14 | public long Id { get; set; } = 0; 15 | 16 | /// 17 | /// Name of the Server (must be unique per Project and a valid hostname as per RFC 1123) 18 | /// 19 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 20 | public string Name { get; set; } = string.Empty; 21 | 22 | /// 23 | /// Status of the Server 24 | /// 25 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 26 | public string Status { get; set; } = string.Empty; 27 | 28 | /// 29 | /// Point in time when the Resource was created 30 | /// 31 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 32 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 33 | 34 | /// 35 | /// Public network information. The Server's IPv4 address can be found in public_net->ipv4->ip 36 | /// 37 | [JsonProperty("public_net", NullValueHandling = NullValueHandling.Ignore)] 38 | public PublicNet PublicNet { get; set; } = new PublicNet(); 39 | 40 | /// 41 | /// Private networks information 42 | /// 43 | [JsonProperty("private_net", NullValueHandling = NullValueHandling.Ignore)] 44 | public List PrivateNet { get; set; } = new List(); 45 | 46 | /// 47 | /// Type of Server - determines how much ram, disk and cpu a Server has 48 | /// 49 | [JsonProperty("server_type", NullValueHandling = NullValueHandling.Ignore)] 50 | public ServerType.ServerType ServerType { get; set; } = new ServerType.ServerType(); 51 | 52 | /// 53 | /// Datacenter this Resource is located at 54 | /// 55 | [JsonProperty("datacenter", NullValueHandling = NullValueHandling.Ignore)] 56 | public Datacenter.Datacenter Datacenter { get; set; } = new Datacenter.Datacenter(); 57 | 58 | /// 59 | /// Image 60 | /// 61 | [JsonProperty("image", NullValueHandling = NullValueHandling.Ignore)] 62 | public Image.Image Image { get; set; } = new Image.Image(); 63 | 64 | //[JsonProperty("iso", NullValueHandling = NullValueHandling.Ignore)] 65 | //public object Iso { get; set; } 66 | 67 | /// 68 | /// True if rescue mode is enabled. Server will then boot into rescue system on next reboot 69 | /// 70 | [JsonProperty("rescue_enabled", NullValueHandling = NullValueHandling.Ignore)] 71 | public bool RescueEnabled { get; set; } = false; 72 | 73 | /// 74 | /// True if Server has been locked and is not available to user 75 | /// 76 | [JsonProperty("locked", NullValueHandling = NullValueHandling.Ignore)] 77 | public bool Locked { get; set; } = false; 78 | 79 | //[JsonProperty("backup_window", NullValueHandling = NullValueHandling.Ignore)] 80 | //public object BackupWindow { get; set; } 81 | 82 | /// 83 | /// Outbound Traffic for the current billing period in bytes 84 | /// 85 | [JsonProperty("outgoing_traffic", NullValueHandling = NullValueHandling.Ignore)] 86 | public long OutgoingTraffic { get; set; } 87 | 88 | /// 89 | /// Inbound Traffic for the current billing period in bytes 90 | /// 91 | [JsonProperty("ingoing_traffic", NullValueHandling = NullValueHandling.Ignore)] 92 | public long IngoingTraffic { get; set; } = 0; 93 | 94 | /// 95 | /// Free Traffic for the current billing period in bytes 96 | /// 97 | [JsonProperty("included_traffic", NullValueHandling = NullValueHandling.Ignore)] 98 | public long IncludedTraffic { get; set; } = 0; 99 | 100 | /// 101 | /// Protection configuration for the Server 102 | /// 103 | [JsonProperty("protection", NullValueHandling = NullValueHandling.Ignore)] 104 | public Protection Protection { get; set; } = new Protection(); 105 | 106 | //[JsonProperty("labels", NullValueHandling = NullValueHandling.Ignore)] 107 | //public Labels Labels { get; set; } 108 | 109 | /// 110 | /// IDs of Volumes assigned to this Server 111 | /// 112 | [JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)] 113 | public List Volumes { get; set; } = new List(); 114 | 115 | /// 116 | /// Array of integers (int64) 117 | /// 118 | [JsonProperty("load_balancers", NullValueHandling = NullValueHandling.Ignore)] 119 | public List LoadBalancers { get; set; } = new List(); 120 | 121 | /// 122 | /// Size of the primary Disk 123 | /// 124 | [JsonProperty("primary_disk_size", NullValueHandling = NullValueHandling.Ignore)] 125 | public long PrimaryDiskSize { get; set; } = 0; 126 | 127 | /// 128 | /// Placement Group 129 | /// 130 | [JsonProperty("placement_group", NullValueHandling = NullValueHandling.Ignore)] 131 | public PlacementGroup.PlacementGroup PlacementGroup { get; set; } = new PlacementGroup.PlacementGroup(); 132 | } 133 | 134 | public class Ipv4 135 | { 136 | [JsonProperty("ip", NullValueHandling = NullValueHandling.Ignore)] 137 | public string Ip { get; set; } = string.Empty; 138 | 139 | [JsonProperty("blocked", NullValueHandling = NullValueHandling.Ignore)] 140 | public bool Blocked { get; set; } = false; 141 | 142 | [JsonProperty("dns_ptr", NullValueHandling = NullValueHandling.Ignore)] 143 | public string DnsPtr { get; set; } = string.Empty; 144 | 145 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 146 | public long Id { get; set; } = 0; 147 | } 148 | 149 | public class Ipv6 150 | { 151 | [JsonProperty("ip", NullValueHandling = NullValueHandling.Ignore)] 152 | public string Ip { get; set; } = string.Empty; 153 | 154 | [JsonProperty("blocked", NullValueHandling = NullValueHandling.Ignore)] 155 | public bool Blocked { get; set; } = false; 156 | 157 | //[JsonProperty("dns_ptr", NullValueHandling = NullValueHandling.Ignore)] 158 | //public string DnsPtr { get; set; } = string.Empty; 159 | 160 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 161 | public long Id { get; set; } = 0; 162 | } 163 | 164 | public class PublicNet 165 | { 166 | [JsonProperty("ipv4", NullValueHandling = NullValueHandling.Ignore)] 167 | public Ipv4 Ipv4 { get; set; } = new Ipv4(); 168 | 169 | [JsonProperty("ipv6", NullValueHandling = NullValueHandling.Ignore)] 170 | public Ipv6 Ipv6 { get; set; } = new Ipv6(); 171 | 172 | [JsonProperty("floating_ips", NullValueHandling = NullValueHandling.Ignore)] 173 | public List FloatingIps { get; set; } = new List(); 174 | 175 | [JsonProperty("firewalls", NullValueHandling = NullValueHandling.Ignore)] 176 | public List Firewalls { get; set; } = new List(); 177 | } 178 | 179 | public class PrivateNet 180 | { 181 | [JsonProperty("network", NullValueHandling = NullValueHandling.Ignore)] 182 | public long Network { get; set; } = 0; 183 | 184 | [JsonProperty("ip", NullValueHandling = NullValueHandling.Ignore)] 185 | public string Ip { get; set; } = string.Empty; 186 | 187 | //[JsonProperty("alias_ips", NullValueHandling = NullValueHandling.Ignore)] 188 | //public List AliasIps { get; set; } 189 | 190 | [JsonProperty("mac_address", NullValueHandling = NullValueHandling.Ignore)] 191 | public string MacAddress { get; set; } = string.Empty; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/ServerType/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using HetznerCloudApi.Object.Universal; 3 | using Newtonsoft.Json; 4 | 5 | namespace HetznerCloudApi.Object.ServerType.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("server_types", NullValueHandling = NullValueHandling.Ignore)] 10 | public List ServerTypes { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/ServerType/ServerType.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace HetznerCloudApi.Object.ServerType 5 | { 6 | public class ServerType 7 | { 8 | /// 9 | /// ID of the Server type 10 | /// 11 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 12 | public long Id { get; set; } = 0; 13 | 14 | /// 15 | /// Unique identifier of the Server type 16 | /// 17 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 18 | public string Name { get; set; } = string.Empty; 19 | 20 | /// 21 | /// Description of the Server type 22 | /// 23 | [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] 24 | public string Description { get; set; } = string.Empty; 25 | 26 | /// 27 | /// Number of cpu cores a Server of this type will have 28 | /// 29 | [JsonProperty("cores", NullValueHandling = NullValueHandling.Ignore)] 30 | public long Cores { get; set; } = 0; 31 | 32 | /// 33 | /// Memory a Server of this type will have in GB 34 | /// 35 | [JsonProperty("memory", NullValueHandling = NullValueHandling.Ignore)] 36 | public double Memory { get; set; } = 0; 37 | 38 | /// 39 | /// Disk size a Server of this type will have in GB 40 | /// 41 | [JsonProperty("disk", NullValueHandling = NullValueHandling.Ignore)] 42 | public long Disk { get; set; } = 0; 43 | 44 | /// 45 | /// This field is deprecated. Use the deprecation object instead 46 | /// 47 | [JsonProperty("deprecated", NullValueHandling = NullValueHandling.Ignore)] 48 | public bool Deprecated { get; set; } = false; 49 | 50 | /// 51 | /// Prices in different Locations 52 | /// 53 | [JsonProperty("prices", NullValueHandling = NullValueHandling.Ignore)] 54 | public List Prices { get; set; } = new List(); 55 | 56 | /// 57 | /// Possible enum values: 58 | /// localnetwork 59 | /// Type of Server boot drive. Local has higher speed. Network has better availability. 60 | /// 61 | [JsonProperty("storage_type", NullValueHandling = NullValueHandling.Ignore)] 62 | public string StorageType { get; set; } = string.Empty; 63 | 64 | /// 65 | /// Possible enum values: 66 | /// shareddedicated 67 | /// Type of cpu 68 | /// 69 | [JsonProperty("cpu_type", NullValueHandling = NullValueHandling.Ignore)] 70 | public string CpuType { get; set; } = string.Empty; 71 | 72 | /// 73 | /// Possible enum values: 74 | /// x86arm 75 | /// Type of cpu architecture 76 | /// 77 | [JsonProperty("architecture", NullValueHandling = NullValueHandling.Ignore)] 78 | public string Architecture { get; set; } = string.Empty; 79 | 80 | /// 81 | /// Free traffic per month in bytes 82 | /// 83 | [JsonProperty("included_traffic", NullValueHandling = NullValueHandling.Ignore)] 84 | public double IncludedTraffic { get; set; } 85 | 86 | //[JsonProperty("deprecation")] 87 | //public object Deprecation { get; set; } 88 | 89 | public class Price 90 | { 91 | /// 92 | /// Name of the Location the price is for 93 | /// 94 | [JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)] 95 | public string Location { get; set; } = string.Empty; 96 | 97 | /// 98 | /// Hourly costs for a Server type in this Location 99 | /// 100 | [JsonProperty("price_hourly", NullValueHandling = NullValueHandling.Ignore)] 101 | public PriceHourly PriceHourly { get; set; } = new PriceHourly(); 102 | 103 | [JsonProperty("price_monthly", NullValueHandling = NullValueHandling.Ignore)] 104 | public PriceMonthly PriceMonthly { get; set; } = new PriceMonthly(); 105 | } 106 | 107 | public class PriceHourly 108 | { 109 | /// 110 | /// Price without VAT 111 | /// 112 | [JsonProperty("net", NullValueHandling = NullValueHandling.Ignore)] 113 | public string Net { get; set; } = string.Empty; 114 | 115 | /// 116 | /// Price with VAT added 117 | /// 118 | [JsonProperty("gross", NullValueHandling = NullValueHandling.Ignore)] 119 | public string Gross { get; set; } = string.Empty; 120 | } 121 | 122 | public class PriceMonthly 123 | { 124 | /// 125 | /// Price without VAT 126 | /// 127 | [JsonProperty("net", NullValueHandling = NullValueHandling.Ignore)] 128 | public string Net { get; set; } = string.Empty; 129 | 130 | /// 131 | /// Price with VAT added 132 | /// 133 | [JsonProperty("gross", NullValueHandling = NullValueHandling.Ignore)] 134 | public string Gross { get; set; } = string.Empty; 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/SshKey/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.SshKey.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("ssh_keys", NullValueHandling = NullValueHandling.Ignore)] 10 | public List SshKeys { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/SshKey/SshKey.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | 4 | namespace HetznerCloudApi.Object.SshKey 5 | { 6 | public class SshKey 7 | { 8 | /// 9 | /// ID of the Resource 10 | /// 11 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 12 | public long Id { get; set; } = 0; 13 | 14 | /// 15 | /// Name of the Resource. Must be unique per Project. 16 | /// 17 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 18 | public string Name { get; set; } = string.Empty; 19 | 20 | /// 21 | /// Fingerprint of public key 22 | /// 23 | [JsonProperty("fingerprint", NullValueHandling = NullValueHandling.Ignore)] 24 | public string Fingerprint { get; set; } = string.Empty; 25 | 26 | /// 27 | /// Public key 28 | /// 29 | [JsonProperty("public_key", NullValueHandling = NullValueHandling.Ignore)] 30 | public string PublicKey { get; set; } = string.Empty; 31 | 32 | //[JsonProperty("labels", NullValueHandling = NullValueHandling.Ignore)] 33 | //public Labels Labels { get; set; } 34 | 35 | [JsonProperty("is_default", NullValueHandling = NullValueHandling.Ignore)] 36 | public bool IsDefault { get; set; } = false; 37 | 38 | /// 39 | /// Point in time when the Resource was created 40 | /// 41 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 42 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Universal/Enum.cs: -------------------------------------------------------------------------------- 1 | namespace HetznerCloudApi.Object.Universal 2 | { 3 | public enum eDataCenter 4 | { 5 | /// 6 | /// Falkenstein | eu-central 7 | /// 8 | fsn1, 9 | 10 | /// 11 | /// Nuremberg | eu-central 12 | /// 13 | nbg1, 14 | 15 | /// 16 | /// Helsinki | eu-central 17 | /// 18 | hel1, 19 | 20 | /// 21 | /// Ashburn, VA |us-east 22 | /// 23 | ash, 24 | 25 | /// 26 | /// Hillsboro, OR | us-west 27 | /// 28 | hil, 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Universal/Error.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace HetznerCloudApi.Object.Universal 4 | { 5 | public class Error 6 | { 7 | [JsonProperty("message")] 8 | public string Message { get; set; } = string.Empty; 9 | 10 | [JsonProperty("code")] 11 | public string Code { get; set; } = string.Empty; 12 | 13 | //[JsonProperty("details")] 14 | //public object Details { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Universal/Meta.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace HetznerCloudApi.Object.Universal 4 | { 5 | public class Meta 6 | { 7 | [JsonProperty("pagination", NullValueHandling = NullValueHandling.Ignore)] 8 | public Pagination Pagination { get; set; } = new Pagination(); 9 | } 10 | 11 | public class Pagination 12 | { 13 | [JsonProperty("page", NullValueHandling = NullValueHandling.Ignore)] 14 | public long Page { get; set; } = 0; 15 | 16 | [JsonProperty("per_page", NullValueHandling = NullValueHandling.Ignore)] 17 | public long PerPage { get; set; } = 0; 18 | 19 | [JsonProperty("previous_page", NullValueHandling = NullValueHandling.Ignore)] 20 | public long PreviousPage { get; set; } = 0; 21 | 22 | [JsonProperty("next_page", NullValueHandling = NullValueHandling.Ignore)] 23 | public long NextPage { get; set; } = 0; 24 | 25 | [JsonProperty("last_page", NullValueHandling = NullValueHandling.Ignore)] 26 | public long LastPage { get; set; } = 0; 27 | 28 | [JsonProperty("total_entries", NullValueHandling = NullValueHandling.Ignore)] 29 | public long TotalEntries { get; set; } = 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Universal/Protection.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace HetznerCloudApi.Object.Universal 4 | { 5 | public class Protection 6 | { 7 | /// 8 | /// If true, prevents the Resource from being deleted 9 | /// 10 | [JsonProperty("delete", NullValueHandling = NullValueHandling.Ignore)] 11 | public bool Delete { get; set; } = false; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Volume/Get/Response.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi.Object.Universal; 2 | using Newtonsoft.Json; 3 | using System.Collections.Generic; 4 | 5 | namespace HetznerCloudApi.Object.Volume.Get 6 | { 7 | public class Response 8 | { 9 | [JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)] 10 | public List Volumes { get; set; } = new List(); 11 | 12 | [JsonProperty("meta", NullValueHandling = NullValueHandling.Ignore)] 13 | public Meta Meta { get; set; } = new Meta(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /HetznerCloudApi/Object/Volume/Volume.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using HetznerCloudApi.Object.Universal; 4 | 5 | namespace HetznerCloudApi.Object.Volume 6 | { 7 | public class Volume 8 | { 9 | /// 10 | /// Point in time when the Resource was created 11 | /// 12 | [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] 13 | public DateTime Created { get; set; } = new DateTime(1900, 01, 01); 14 | 15 | /// 16 | /// Filesystem of the Volume if formatted on creation, null if not formatted on creation 17 | /// 18 | [JsonProperty("format", NullValueHandling = NullValueHandling.Ignore)] 19 | public string Format { get; set; } = string.Empty; 20 | 21 | /// 22 | /// ID of the Resource 23 | /// 24 | [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] 25 | public long Id { get; set; } = 0; 26 | 27 | //[JsonProperty("labels")] 28 | //public Labels Labels { get; set; } 29 | 30 | /// 31 | /// Device path on the file system for the Volume 32 | /// 33 | [JsonProperty("linux_device", NullValueHandling = NullValueHandling.Ignore)] 34 | public string LinuxDevice { get; set; } = string.Empty; 35 | 36 | /// 37 | /// Location of the Volume. Volume can only be attached to Servers in the same Location. 38 | /// 39 | [JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)] 40 | public Location.Location Location { get; set; } = new Location.Location(); 41 | 42 | /// 43 | /// Name of the Resource. Must be unique per Project. 44 | /// 45 | [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] 46 | public string Name { get; set; } = string.Empty; 47 | 48 | /// 49 | /// Protection configuration for the Resource 50 | /// 51 | [JsonProperty("protection", NullValueHandling = NullValueHandling.Ignore)] 52 | public Protection Protection { get; set; } = new Protection(); 53 | 54 | /// 55 | /// ID of the Server the Volume is attached to, null if it is not attached at all 56 | /// 57 | [JsonProperty("server", NullValueHandling = NullValueHandling.Ignore)] 58 | public long Server { get; set; } = 0; 59 | 60 | /// 61 | /// Size in GB of the Volume 62 | /// 63 | [JsonProperty("size", NullValueHandling = NullValueHandling.Ignore)] 64 | public long Size { get; set; } = 0; 65 | 66 | /// 67 | /// Current status of the Volume 68 | /// 69 | [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] 70 | public string Status { get; set; } = string.Empty; 71 | } 72 | 73 | public enum VolumeFormat 74 | { 75 | ext4, 76 | xfs, 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /HetznerCloudApi/icon-circle-cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljchuello/HetznerCloud.API/64f7eaaf3070dface8fb24f3bd2b10964da76b75/HetznerCloudApi/icon-circle-cloud.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Leonardo Chuello 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌐 Hetzner Cloud API 2 | 3 | ![Hetzner](https://github.com/ljchuello/HetznerCloud.API/assets/5316348/4e1b4486-5cfe-4470-9055-c8ac3f965249) 4 | 5 | This project is your complete guide to exploring and utilizing the Hetzner Cloud API. Here, you'll find everything you need to integrate your projects with one of the most powerful and efficient cloud platforms. 6 | 7 | **Key Features:** 8 | 9 | * **Quick Start:** Begin with simple examples to connect and use the API. 🖥️ 10 | * **Detailed API Reference:** Each endpoint is explained with code examples, making it easy even for beginners. 📚 11 | * **Use Cases:** Discover how other developers are leveraging the API in real-world scenarios. 💡 12 | * **Security and Best Practices:** Learn to use the API securely and efficiently. 🔐 13 | * **Support and Community:** Join our community and get help when you need it. 👥 14 | 15 | **Who is This GitBook For?** 16 | 17 | * **System and Web Developers:** If you program in C#, Angular, or any other language, you'll find useful resources here. 18 | * **IT and Network Professionals:** Tips for securing and optimizing your cloud projects. 19 | 20 | **Start Now!** Navigate the chapters, dive into the example codes, and take your cloud projects to the next level. We're here to help you every step of the way! 🌟 21 | 22 | *** 23 | 24 | ## 📖 The Wiki 25 | 26 | To see all the features and functionality, visit [the Wiki](https://hetzner.ljchuello.com/) 27 | 28 | *** 29 | 30 | ## 🔗 Compatibility 31 | 32 | This library is developed in **.NET Standard 2.0** and is compatible with all **.NET, .NET Core and .NET Framework**, it can also be used in Console projects, Web API, Class Library and even with Blazor WASM . 33 | 34 | | .NET implementation | Version support | 35 | | ------------------- | --------------------------------------------- | 36 | | .NET and .NET Core | 2.0, 2.1, 2.2, 3.0, 3.1, 5.0, 6.0, 7.0, 8.0 | 37 | | .NET Framework | 4.6.1 2, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1 | 38 | 39 | *** 40 | 41 | ## 🔧 Installation 42 | 43 | To install you must go to Nuget package manager and search for **HetznerCloud.API** and then install. 44 | 45 | [**NuGet Package**](https://www.nuget.org/packages/HetznerCloud.API/) 46 | 47 | ```powershell 48 | PM> dotnet add package HetznerCloud.API 49 | ``` 50 | 51 | *** 52 | 53 | ## :heavy\_check\_mark: Implemented functionality 54 | 55 | :heavy\_check\_mark: - Available on API, implemented\ 56 | :x: - Available on API, not implemented\ 57 | :heavy\_minus\_sign: - Not available on API 58 | 59 | | | Get all | Get one | Create | Update | Delete | Actions | 60 | | ----------------- | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | :------------------: | 61 | | Actions | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | 62 | | Datacenters | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | 63 | | Firewalls | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | 64 | | Firewalls Actions | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_check\_mark: | 65 | | Images | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | 66 | | Locations | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | 67 | | Networks | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | 68 | | Networks Actions | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_check\_mark: | 69 | | Servers | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | 70 | | Server Types | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | 71 | | SSH Keys | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | 72 | | Volumes | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_check\_mark: | :heavy\_minus\_sign: | 73 | | Volumes Actions | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_minus\_sign: | :heavy\_check\_mark: | 74 | -------------------------------------------------------------------------------- /Test/Program.cs: -------------------------------------------------------------------------------- 1 | using HetznerCloudApi; 2 | using HetznerCloudApi.Object.Server; 3 | using HetznerCloudApi.Object.Universal; 4 | 5 | namespace Test 6 | { 7 | internal class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | MainAsync().Wait(); 12 | } 13 | 14 | static async Task MainAsync() 15 | { 16 | try 17 | { 18 | HetznerCloudClient hetznerCloudClient = new HetznerCloudClient("ApiKey"); 19 | hetznerCloudClient = new HetznerCloudClient(await File.ReadAllTextAsync("D:\\HetznerApiKey.txt")); 20 | } 21 | catch (Exception ex) 22 | { 23 | Console.WriteLine(ex); 24 | Console.ReadLine(); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Test/Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljchuello/HetznerCloud.API/64f7eaaf3070dface8fb24f3bd2b10964da76b75/icon_128.png --------------------------------------------------------------------------------