feat(volumes and firewalls): enable volumes and firewalls management.
This commit is contained in:
		@@ -3,6 +3,6 @@
 | 
			
		||||
 */
 | 
			
		||||
export const commitinfo = {
 | 
			
		||||
  name: '@apiclient.xyz/hetznercloud',
 | 
			
		||||
  version: '1.0.18',
 | 
			
		||||
  version: '1.1.0',
 | 
			
		||||
  description: 'an unofficial api client for the hetzner cloud api'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,74 @@
 | 
			
		||||
// Hetzner Cloud Firewall Class
 | 
			
		||||
import type { HetznerAccount } from './classes.account.js';
 | 
			
		||||
import * as plugins from './hetznercloud.plugins.js';
 | 
			
		||||
import * as types from './types.js';
 | 
			
		||||
 | 
			
		||||
export class HetznerFirewall {
 | 
			
		||||
  // STATIC
 | 
			
		||||
  public static create = async (
 | 
			
		||||
    hetznerAccountRefArg: HetznerAccount,
 | 
			
		||||
    optionsArg: {
 | 
			
		||||
      name: string;
 | 
			
		||||
      labels?: {[key: string]: string},
 | 
			
		||||
      rules: types.IFirewall['rules'],
 | 
			
		||||
    }
 | 
			
		||||
  ) => {
 | 
			
		||||
    const firewall = new HetznerFirewall(hetznerAccountRefArg);
 | 
			
		||||
 | 
			
		||||
    const createFirewallUrl = '/firewalls';
 | 
			
		||||
    const createFirewallPayload: types.TFirewallCreateRequestBody = {
 | 
			
		||||
      name: optionsArg.name,
 | 
			
		||||
      labels: optionsArg.labels || {} as any,
 | 
			
		||||
      rules: optionsArg.rules
 | 
			
		||||
    };
 | 
			
		||||
    const response = await firewall.hetznerAccountRef.request(
 | 
			
		||||
      'POST',
 | 
			
		||||
      createFirewallUrl,
 | 
			
		||||
      createFirewallPayload
 | 
			
		||||
    );
 | 
			
		||||
    firewall.data = (response.body as types.TFirewallCreateResponseBody).firewall;
 | 
			
		||||
    return firewall;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getFirewalls = async (hetznerAccountRefArg: HetznerAccount) => {
 | 
			
		||||
    const firewallsGetUrl = '/firewalls';
 | 
			
		||||
    const response = await hetznerAccountRefArg.request('GET', firewallsGetUrl, {});
 | 
			
		||||
    const firewallsDataArray = (response.body as types.TFirewallsGetResponseBody).firewalls;
 | 
			
		||||
    const firewalls: HetznerFirewall[] = [];
 | 
			
		||||
    for (const firewallData of firewallsDataArray) {
 | 
			
		||||
      const firewall = new HetznerFirewall(hetznerAccountRefArg);
 | 
			
		||||
      firewall.data = firewallData;
 | 
			
		||||
      firewalls.push(firewall);
 | 
			
		||||
    }
 | 
			
		||||
    return firewalls;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getFirewallsByLabel = async (hetznerAccountRefArg: HetznerAccount, labelObject: {[key: string]: string}) => {
 | 
			
		||||
    const firewalls = await HetznerFirewall.getFirewalls(hetznerAccountRefArg);
 | 
			
		||||
    const results: HetznerFirewall[] = [];
 | 
			
		||||
    for (const firewall of firewalls) {
 | 
			
		||||
      let isMatch = true;
 | 
			
		||||
      for (const key in labelObject) {
 | 
			
		||||
        if (firewall.data.labels[key] !== labelObject[key]) {
 | 
			
		||||
          isMatch = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (isMatch) {
 | 
			
		||||
        results.push(firewall);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return results;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // INSTANCE
 | 
			
		||||
  public data: types.IFirewall;
 | 
			
		||||
  public hetznerAccountRef: HetznerAccount;
 | 
			
		||||
 | 
			
		||||
  constructor(hetznerAccountRefArg: HetznerAccount) {
 | 
			
		||||
    this.hetznerAccountRef = hetznerAccountRefArg;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async delete() {
 | 
			
		||||
    await this.hetznerAccountRef.request('DELETE', `/firewalls/${this.data.id}`, {});
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								ts/classes.volume.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								ts/classes.volume.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
import type { HetznerAccount } from './classes.account.js';
 | 
			
		||||
import type { HetznerServer } from './classes.server.js';
 | 
			
		||||
import * as plugins from './hetznercloud.plugins.js';
 | 
			
		||||
import * as types from './types.js';
 | 
			
		||||
 | 
			
		||||
export class Volume {
 | 
			
		||||
  public static create = async (
 | 
			
		||||
    hetznerAccountRefArg: HetznerAccount,
 | 
			
		||||
    optionsArg: {
 | 
			
		||||
      name: string;
 | 
			
		||||
      size: number;
 | 
			
		||||
      location: types.THetznerCloudLocationName;
 | 
			
		||||
      labels?: {[key: string]: string},
 | 
			
		||||
      server: HetznerServer,
 | 
			
		||||
    }
 | 
			
		||||
  ) => {
 | 
			
		||||
    const volume = new Volume(hetznerAccountRefArg);
 | 
			
		||||
 | 
			
		||||
    const createVolumeUrl = '/volumes';
 | 
			
		||||
    const createVolumePayload: types.TVolumeCreateRequestBody = {
 | 
			
		||||
      name: optionsArg.name,
 | 
			
		||||
      size: optionsArg.size,
 | 
			
		||||
      location: optionsArg.location,
 | 
			
		||||
      labels: optionsArg.labels || {} as any,
 | 
			
		||||
      server: optionsArg.server.data.id,
 | 
			
		||||
      format: 'xfs'
 | 
			
		||||
    };
 | 
			
		||||
    const response = await volume.hetznerAccountRef.request(
 | 
			
		||||
      'POST',
 | 
			
		||||
      createVolumeUrl,
 | 
			
		||||
      createVolumePayload
 | 
			
		||||
    );
 | 
			
		||||
    volume.data = (response.body as types.TVolumeCreateResponseBody).volume;
 | 
			
		||||
    return volume;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getVolumes = async (hetznerAccountRefArg: HetznerAccount) => {
 | 
			
		||||
    const volumesGetUrl = '/volumes';
 | 
			
		||||
    const response = await hetznerAccountRefArg.request('GET', volumesGetUrl, {});
 | 
			
		||||
    const volumesDataArray = (response.body as types.TVolumeGetResponseBody).volumes;
 | 
			
		||||
    const volumes: Volume[] = [];
 | 
			
		||||
    for (const volumeData of volumesDataArray) {
 | 
			
		||||
      const volume = new Volume(hetznerAccountRefArg);
 | 
			
		||||
      volume.data = volumeData;
 | 
			
		||||
      volumes.push(volume);
 | 
			
		||||
    }
 | 
			
		||||
    return volumes;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static getVolumesByLabel = async (hetznerAccountRefArg: HetznerAccount, labelObject: {[key: string]: string}) => {
 | 
			
		||||
    const volumes = await Volume.getVolumes(hetznerAccountRefArg);
 | 
			
		||||
    const results: Volume[] = [];
 | 
			
		||||
    for (const volume of volumes) {
 | 
			
		||||
      let isMatch = true;
 | 
			
		||||
      for (const key in labelObject) {
 | 
			
		||||
        if (volume.data.labels[key] !== labelObject[key]) {
 | 
			
		||||
          isMatch = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (isMatch) {
 | 
			
		||||
        results.push(volume);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return results;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public data: types.IVolume;
 | 
			
		||||
  public hetznerAccountRef: HetznerAccount;
 | 
			
		||||
 | 
			
		||||
  constructor(hetznerAccountRefArg: HetznerAccount) {
 | 
			
		||||
    this.hetznerAccountRef = hetznerAccountRefArg;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public delete = async () => {
 | 
			
		||||
    await this.hetznerAccountRef.request('DELETE', `/volumes/${this.data.id}`, {});
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,2 +1,4 @@
 | 
			
		||||
export * from './classes.account.js';
 | 
			
		||||
export * from './classes.server.js';
 | 
			
		||||
export * from './classes.volume.js';
 | 
			
		||||
export * from './classes.firewall.js';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								ts/types.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								ts/types.ts
									
									
									
									
									
								
							@@ -9,6 +9,7 @@ export type TServersGetRequestBody = {};
 | 
			
		||||
export type TServersGetResponseBody = plugins.hetznerOpenapi.paths['/servers']['get']['responses']['200']['content']['application/json'];
 | 
			
		||||
export type TServerCreateRequestBody = plugins.hetznerOpenapi.paths['/servers']['post']['requestBody']['content']['application/json'];
 | 
			
		||||
export type TServerCreateResponseBody = plugins.hetznerOpenapi.paths['/servers']['post']['responses']['201']['content']['application/json'];
 | 
			
		||||
export type TServerDeleteRequestBody = plugins.hetznerOpenapi.paths['/servers/{id}']['delete'];
 | 
			
		||||
 | 
			
		||||
// server types
 | 
			
		||||
export type THetznerCloudServerName =
 | 
			
		||||
@@ -39,4 +40,20 @@ export type THetznerCloudServerName =
 | 
			
		||||
  | 'cpx90';
 | 
			
		||||
 | 
			
		||||
// location types
 | 
			
		||||
export type THetznerCloudLocationName = 'fsn1' | 'nbg1' | 'hel1' | 'ash' | 'hil';
 | 
			
		||||
export type THetznerCloudLocationName = 'fsn1' | 'nbg1' | 'hel1' | 'ash' | 'hil';
 | 
			
		||||
 | 
			
		||||
// volumes
 | 
			
		||||
export type IVolume = plugins.hetznerOpenapi.paths['/volumes/{id}']['get']['responses']['200']['content']['application/json']['volume'];
 | 
			
		||||
export type TVolumeGetRequestBody = {};
 | 
			
		||||
export type TVolumeGetResponseBody = plugins.hetznerOpenapi.paths['/volumes']['get']['responses']['200']['content']['application/json'];
 | 
			
		||||
export type TVolumeCreateRequestBody = plugins.hetznerOpenapi.paths['/volumes']['post']['requestBody']['content']['application/json'];
 | 
			
		||||
export type TVolumeCreateResponseBody = plugins.hetznerOpenapi.paths['/volumes']['post']['responses']['201']['content']['application/json'];
 | 
			
		||||
export type TVolumeDeleteRequestBody = plugins.hetznerOpenapi.paths['/volumes/{id}']['delete'];
 | 
			
		||||
 | 
			
		||||
// firewalls
 | 
			
		||||
export type IFirewall = plugins.hetznerOpenapi.paths['/firewalls/{id}']['get']['responses']['200']['content']['application/json']['firewall'];
 | 
			
		||||
export type TFirewallsGetRequestBody = {};
 | 
			
		||||
export type TFirewallsGetResponseBody = plugins.hetznerOpenapi.paths['/firewalls']['get']['responses']['200']['content']['application/json'];
 | 
			
		||||
export type TFirewallCreateRequestBody = plugins.hetznerOpenapi.paths['/firewalls']['post']['requestBody']['content']['application/json'];
 | 
			
		||||
export type TFirewallCreateResponseBody = plugins.hetznerOpenapi.paths['/firewalls']['post']['responses']['201']['content']['application/json'];
 | 
			
		||||
export type TFirewallDeleteRequestBody = plugins.hetznerOpenapi.paths['/firewalls/{id}']['delete'];
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user