def createServer(name, image): #freebsd = snapid="8322744" #image=Image(type="snapshot", id=snapid) sysImage = True if image=="debian": image_name = "debian-10" elif image == "centos": image_name = "centos-8" elif image == "freebsd": snap_id = "8322744" sysImage = False elif image == "ubuntu": image_name = "ubuntu-18.04" if sysImage: response = client.servers.create(name=name, server_type=ServerType("cx11"), image=Image(name=image_name)) else: response = client.servers.create(name=name, server_type=ServerType("cx11"), image=Image(type="snapshot", id=snap_id)) server = response.server serverData = dict() serverData['id'] = server.id serverData['ip'] = server.public_net.ipv4.ip serverData['pwd'] = response.root_password add_hetzner(name, server.id, server.public_net.ipv4.ip, "cx11", response.root_password) return serverData
def test_change_type_with_server_type_name(self, servers_client, server, generic_action): servers_client._client.request.return_value = generic_action action = servers_client.change_type(server, ServerType(name="cx11"), upgrade_disk=True) servers_client._client.request.assert_called_with(url="/servers/1/actions/change_type", method="POST", json={"server_type": "cx11", "upgrade_disk": True}) assert action.id == 1 assert action.progress == 0
def test_create_with_datacenter(self, servers_client, response_create_simple_server): servers_client._client.request.return_value = response_create_simple_server response = servers_client.create( "my-server", server_type=ServerType(name="cx11"), image=Image(id=4711), datacenter=Datacenter(id=1) ) servers_client._client.request.assert_called_with( url="/servers", method="POST", json={ 'name': "my-server", 'server_type': "cx11", 'image': 4711, 'datacenter': 1, "start_after_create": True } ) bound_server = response.server assert bound_server._client is servers_client assert bound_server.id == 1 assert bound_server.name == "my-server"
def test_change_type(self, hetzner_client, bound_server, generic_action): hetzner_client.request.return_value = generic_action action = bound_server.change_type(ServerType(name="cx11"), upgrade_disk=True) hetzner_client.request.assert_called_with(url="/servers/14/actions/change_type", method="POST", json={"server_type": "cx11", "upgrade_disk": True}) assert action.id == 1 assert action.progress == 0
def test_create(self, hetzner_client): response = hetzner_client.servers.create( "my-server", server_type=ServerType(name="cx11"), image=Image(name="ubuntu-16.04"), ssh_keys=[SSHKey(name="my-ssh-key")], volumes=[Volume(id=1)], user_data= "#cloud-config\\nruncmd:\\n- [touch, /root/cloud-init-worked]\\n", location=Location(name="nbg1"), automount=False) server = response.server action = response.action next_actions = response.next_actions root_password = response.root_password assert server.id == 42 assert server.volumes == [] assert server.server_type.id == 1 assert server.datacenter.id == 1 assert server.image.id == 4711 assert action.id == 1 assert action.command == "create_server" assert len(next_actions) == 1 assert next_actions[0].id == 13 assert next_actions[0].command == "start_server" assert root_password == "YItygq1v3GYjjMomLaKc"
def _create_instance(self, defn) -> None: if not self.public_client_key: (private, public) = create_key_pair(type="ed25519") self.public_client_key = public self.private_client_key = private if not self.public_host_key: (private, public) = create_key_pair(type="ed25519") self.public_host_key = public self.private_host_key = private location: BoundLocation = self.get_client().locations.get_by_name( defn.location) ssh_keys: List[BoundSSHKey] = [ self._create_ssh_key(self.public_client_key) ] # Ensure host keys get injected into the base OS user_data = ("#cloud-config\n" "ssh_keys:\n" " ed25519_public: {0}\n" " ed25519_private: |\n" " {1}").format( self.public_host_key, self.private_host_key.replace("\n", "\n ")) self.logger.log_start( f"creating {defn.server_type} server at {location.description}...") response = self.get_client().servers.create( name=defn.server_name, labels={ **self.get_common_labels(), **dict(defn.labels) }, location=location, server_type=ServerType(defn.server_type), ssh_keys=ssh_keys, user_data=user_data, image=Image(name="ubuntu-20.04"), # for lustration start_after_create=True, ) self.state = self.STARTING self.wait_on_action(response.action) with self.depl._db: self.vm_id = response.server.id self.public_ipv4 = response.server.public_net.ipv4.ip self.public_ipv6 = response.server.public_net.ipv6.ip self.server_name = defn.server_name self.server_type = defn.server_type self.legacy_if_scheme = defn.server_type.startswith("cx") self.location = defn.location self.labels = dict(defn.labels) self.private_host_key = None known_hosts.add(self.public_ipv4, self.public_host_key) self.logger.log_end(f"{self.public_ipv4}")
async def _create_node( self, suffix: str, servertype: str, datacenter: str, image: str, ip: str, labels: Union[Dict[str, str], None] = None, ) -> NodeABC: name = f'{self._prefix:s}-node-{suffix:s}' self._log.info('Creating node %s ...', name) _ = self._client.servers.create( name=name, server_type=ServerType(name=servertype), image=Image(name=image), datacenter=Datacenter(name=datacenter), ssh_keys=[self._ssh_key], firewalls=[self._firewall], labels=labels, ) self._log.info('Waiting for node %s to become available ...', name) while True: server = self._client.servers.get_by_name(name=name) if server.status == Server.STATUS_RUNNING: break await sleep(self._wait) self._log.info('Attaching network to node %s ...', name) server.attach_to_network( network=self._network, ip=ip, ) self._log.info('Bootstrapping node %s ...', name) node = await Node.from_async( server=server, client=self._client, fn_private=self._fn_private, prefix=self._prefix, wait=self._wait, log=self._log, ) await node.bootstrap() # TODO param? return node
def create_vm(self, vm_name, vm_model, vm_os_image): """ Provision a new VM """ self.logger.debug(f"Creating VM {vm_name}") response = self.client.servers.create( name=vm_name, server_type=ServerType(vm_model), ssh_keys=self.client.ssh_keys.get_all(), image=Image(name=vm_os_image)) response.action.wait_until_finished() return response.server
def deploy_instance(self, name) -> None: log.info(f"hcloud: Deploying instance with name {name}") launch_config = self.launch.copy() labels = launch_config.get("labels", dict()) labels.update({"scalr": self.filter}) params = { "name": name, "labels": labels, "server_type": ServerType(launch_config["server_type"]), "image": Image(launch_config["image"]), "ssh_keys": [SSHKey(ssh_key) for ssh_key in launch_config["ssh_keys"]], "location": Location(launch_config["location"]), "user_data": launch_config["user_data"], } self.hcloud.servers.create(**params)
def create(): with open(data_file, "r") as file: data = json.load(file) client = Client(token=data["token"]) response = client.servers.create("win10-OCR", server_type=ServerType(name="cx41"), image=Image(id=22859215), networks=[Network(id=135205)], location=Location(id=2)) server = response.server data["server_id"] = f"{server.id}" with open(data_file, "w") as file: json.dump(data, file, indent=4) click.echo("creation complete")
def test_create_with_firewalls(self, servers_client, response_create_simple_server): servers_client._client.request.return_value = response_create_simple_server firewalls = [ Firewall(id=1), BoundFirewall(mock.MagicMock(), dict(id=2)) ] response = servers_client.create("my-server", server_type=ServerType(name="cx11"), image=Image(id=4711), firewalls=firewalls, start_after_create=False) servers_client._client.request.assert_called_with( url="/servers", method="POST", json={ 'name': "my-server", 'server_type': "cx11", 'image': 4711, 'firewalls': [{ "firewall": 1 }, { "firewall": 2 }], "start_after_create": False }) bound_server = response.server bound_action = response.action next_actions = response.next_actions root_password = response.root_password assert root_password == "YItygq1v3GYjjMomLaKc" assert bound_server._client is servers_client assert bound_server.id == 1 assert bound_server.name == "my-server" assert isinstance(bound_action, BoundAction) assert bound_action._client == servers_client._client.actions assert bound_action.id == 1 assert bound_action.command == "create_server" assert next_actions[0].id == 13
async def start(self): if self.running == False: print("Starting " + self.name) response = self.client.servers.create( self.name, server_type=ServerType(name=self.servertype), image=Image(self.snapshot), location=Location(self.location), volumes=[Volume(self.volume)]) self.server = response.server #while self.server.status != Server.STATUS_RUNNING: # print(self.server.status) # time.sleep(2) # serv = self.client.servers.get_by_id(self.server.id) # self.server = serv #print("Server is now running") self.running = True else: print(self.name + " is already running")
def __init__( self, cluster: str, config, env_vars: dict = None, bootstrap=None, docker_image: str = None, image: str = None, location: str = None, server_type: str = None, *args, **kwargs, ): super().__init__(*args, **kwargs) self.cluster = cluster self.config = config self.location = location self.bootstrap = bootstrap self.env_vars = env_vars self.client = hcloud.Client(self.config.get("token")) self.server_type = ServerType(server_type) self.image = Image(name=image) self.docker_image = docker_image
def create_server(name, verbose=False): response = client.servers.create(name=name, server_type=ServerType(name="cx11"), datacenter=get_data_center(), image=Image(name="debian-10"), ssh_keys=[ssh_key]) server = response.server main_ip = str(response.server.data_model.public_net.ipv4.ip) if verbose: print(server) print("You can login: "******"ssh -oStrictHostKeyChecking=no root@" + main_ip) try: client.floating_ips.unassign(get_floating_ip()) except APIException: if verbose: print("No need to unassign") if verbose: print("Waiting...") time.sleep(20) if verbose: print("Now assign the ip new") client.floating_ips.assign(get_floating_ip(), server) print(main_ip)
def create_servers(size=SIZE, total=PERFORMERS): """create some servers""" # get the last server number servers = get_servers() if len(servers) > 0: names = [s.name for s in servers] nums = sorted([int(n.split("-")[-1]) for n in names], reverse=True) start = nums[0] + 1 else: start = 0 client = Client(token=TOKEN) key = get_key() image = get_image() st = ServerType(SIZE) for i in range(start, start + total): name = f"{NAME}-{i}" response = client.servers.create(name=name, server_type=st, image=image, ssh_keys=[key]) print(response)
def create_node(self): assert self.ssh_key_id assert self.ssh_custom_key response = self.client.servers.create( name=self.get_rnd_name('node'), server_type=ServerType('cx51'), image=Image(name='debian-10'), ssh_keys=[SSHKey(name=self.key_name)] ) server = response.server ip = server.public_net.ipv4.ip logging.info('CREATED %s' % ip) time.sleep(5) # warm up for _ in range(10): ssh_conn = SSH_Connection(host=ip, user=self.config.get('remote', 'user'), connect_kwargs=self.ssh_custom_key) try: ssh_conn.run('whoami', hide=True) except: time.sleep(5) else: break return ip
from hcloud import Client from hcloud.images.domain import Image from hcloud.server_types.domain import ServerType client = Client(token="{YOUR_API_TOKEN}") # Please paste your API token here between the quotes response = client.servers.create(name="my-server", server_type=ServerType("cx11"), image=Image(name="ubuntu-18.04")) server = response.server print(server) print("Root Password" + response.root_password)
def create( # noqa: C901 self, defn: HetznerCloudDefinition, check: bool, allow_reboot: bool, allow_recreate: bool, ) -> None: self.api_token = defn.api_token if self.state != self.UP: check = True self.set_common_state(defn) if self.api_token and self.api_token != defn.api_token: raise Exception("cannot change api token of an existing instance") # Destroy the instance (if allowed) to handle attribute changes which # require recreating i.e. location if (self.vm_id and allow_recreate and self.location != defn.location and self.depl.logger.confirm( "changing server location requires recreate, are you sure?" )): self._destroy() # Stop the instance (if allowed) to handle attribute changes which # require rebooting i.e. server_type if self.vm_id and allow_reboot and self.server_type != defn.server_type: self.stop() check = True # Check whether the instance hasn't been killed behind our backs. # Handle changed server type. # Restart stopped instances. if self.vm_id and check: instance = self.get_instance() if instance is None or instance.status in {"deleting"}: if not allow_recreate: raise Exception( f"{self.full_name} went away;" " use ‘--allow-recreate’ to create a new one") status = instance.status if instance else "gone" self.logger.log( f"{self.full_name} went away (state ‘{status}’), will recreate" ) self.cleanup_state() # Modify the server type, if desired. TODO store disk size # in state to enable option to later downsize server type. if instance.status == "off" and self.server_type != defn.server_type: self.logger.log_start( f"changing server type from ‘{self.server_type}’ to" f" ‘{defn.server_type}’; may take a few minutes...") instance.change_type(ServerType(defn.server_type), upgrade_disk=True).wait_until_finished() self.logger.log_end("done!") with self.depl._db: self.server_type = defn.server_type self.logger.log("instance was stopped, restarting...") self.start() # Provision the instance. if not self.vm_id: self._create_instance(defn) self.wait_for_ssh() self.state = self.RESCUE self.logger.log_start("running nixos-infect") self.run_command("bash </dev/stdin 2>&1", stdin=open(INFECT_PATH)) self.logger.log("rebooting into NixOS 😎") self.reboot_sync() self.state = self.UP if self.location != defn.location: raise Exception("cannot change location of an existing instance" f" (from ‘{self.location}‘ to ‘{defn.location}‘);" " use ‘--allow-recreate’") if self.server_type != defn.server_type: raise Exception( "cannot change server type of a running instance" f" (from ‘{self.server_type}‘ to ‘{defn.server_type}‘);" " use ‘--allow-reboot’") # Update name or labels if they have changed. if self.server_name != defn.server_name or self.labels != defn.labels: self.logger.log("updating trivial modified attributes") self.get_instance().update(defn.server_name, { **self.get_common_labels(), **dict(defn.labels) }) self._handle_changed_floating_ips(defn, allow_recreate) self._handle_changed_volumes(defn, allow_recreate) self._handle_changed_server_networks(defn, allow_recreate)
from hcloud import Client from hcloud.images.domain import Image from hcloud.server_types.domain import ServerType # Create a client client = Client(token="project-token") # Create 2 servers # Create 2 servers response1 = client.servers.create("Server1", server_type=ServerType(name="cx11"), image=Image(id=4711)) response2 = client.servers.create("Server2", server_type=ServerType(name="cx11"), image=Image(id=4711)) # Get all servers server1 = response1.server server2 = response2.server servers = client.servers.get_all() assert servers[0].id == server1.id assert servers[1].id == server2.id # Create 2 volumes response1 = client.volumes.create(size=15, name="Volume1", location=server1.location) response2 = client.volumes.create(size=10, name="Volume2",
img = find_image(client, args.image) if debug: print(NAME, args.type, args.image, args.datacenter, ssh_key_names, ssh_pub_key, ssh_key_list, packages, file=sys.stderr) response = client.servers.create(name=NAME, server_type=ServerType(args.type), image=img, ssh_keys=ssh_key_list, labels=labels) server = response.server IPADDR = server.data_model.public_net.ipv4.ip model = server.data_model.server_type.data_model print("Machine created: type=%s cpus=%s mem=%sgb disk=%sgb addr=%s" % (model.name, model.cores, model.memory, model.disk, IPADDR), file=sys.stderr) server.change_dns_ptr(IPADDR, NAME + '.hcloud.owncloud.com') # needs an FQDN # CAUTION: keep in sync with ../hcloud_tf/make_machine.sh script = """ exec 1>&2 # all output goes to stderr.
def create(self, defn: HcloudDefinition, check, allow_reboot, allow_recreate): assert isinstance(defn, HcloudDefinition) hetzner = defn.config.hcloud self.token = get_access_token(hetzner) if self.state not in (MachineState.RESCUE, MachineState.UP) or check: self.check() self.set_common_state(defn) self.upgrade_disk = hetzner.upgradeDisk # TODO maybe bootstrap can be automated with vncdotool image_id = self._fetch_image_id(hetzner.image, hetzner.image_selector) if self.image_id is None: self.image_id = image_id elif self.image_id != image_id: self.warn( f"image_id changed from {self.image_id} to {image_id} but can't update image of a VM." ) if self.location is None: self.location = hetzner.location elif self.location != hetzner.location: self.warn( f"location changed from {self.location} to {hetzner.location} but can't update location of a VM." ) if self.vm_id is not None and hetzner.serverType != self.server_type: # TODO Check if server can be upgraded before hitting the Hetzner API # https://docs.hetzner.cloud/#server-actions-change-the-type-of-a-server do_upgrade = True # Only confirm if upgrade_disk is True because then the upgrade can't be undone if self.upgrade_disk: do_upgrade = self.depl.logger.confirm( f"are you sure you want to change Hetzner server {self.name} type from " + f"{self.server_type} to {hetzner.serverType}?") if do_upgrade: self.log_start("Changing Hetzner server type...") self._server.shutdown().wait_until_finished() self.wait_for_down(callback=lambda: self.log_continue(".")) self._server.change_type( ServerType(name=hetzner.serverType), upgrade_disk=self.upgrade_disk).wait_until_finished() self._server.power_on() self.wait_for_up(callback=lambda: self.log_continue(".")) self.log_end("") self.server_type = hetzner.serverType ssh_keys = [ k.name if isinstance(k, ResourceEval) else k for k in hetzner.sshKeys ] if self.state != MachineState.MISSING and ssh_keys != self.ssh_keys: self.logger.warn( f"SSH keys cannot be changed after the server is created.") volume_ids = [] filesystems = {} for volumeopts in hetzner.volumes: volume = volumeopts.volume if isinstance(volume, str): volume_model = self._client.volumes.get_by_name(volume) volume_name = volume volume_id = volume_model.id volume_loc = volume_model.location.name else: volume_res = self.depl.get_typed_resource( volume._name, "hcloud-volume", HcloudVolumeState) volume_name = volume_res.name volume_id = volume_res.hcloud_id assert volume_id is not None volume_loc = volume_res.location if volume_loc != self.location: raise Exception( f"Volume {volume_name!r} is in a different location from server {self.name!r}" ) volume_ids.append(volume_id) if volumeopts.mountPoint is not None: fs = dict(volumeopts.fileSystem) fs["device"] = f"/dev/disk/by-id/scsi-0HC_Volume_{volume_id}" filesystems[volumeopts.mountPoint] = fs has_priv = self._ssh_private_key is not None has_pub = self._ssh_public_key is not None assert has_priv == has_pub if not has_priv: self.log("Generating SSH keypair...") (self._ssh_private_key, self._ssh_public_key) = create_key_pair() if self.vm_id: if self.volume_ids != volume_ids: current = set(self.volume_ids) new = set(volume_ids) volumes_client = self._client.volumes self.log_start("Updating volumes...") for v in current - new: volumes_client.detach(Volume(id=v)) self.log_continue(".") for v in new - current: volumes_client.attach( Volume(id=v), self._server, automount=False).wait_until_finished() self.log_continue(".") self.log_end("") self.volume_ids = volume_ids else: self.log_start( "Creating Hetzner Cloud VM (" + f"image '{image_id}', type '{hetzner.serverType}', location '{hetzner.location}'" + ")...") response = self._client.servers.create( name=self.name, ssh_keys=[SSHKey(name=k) for k in ssh_keys], volumes=[Volume(id=v) for v in volume_ids], server_type=ServerType(self.server_type), image=Image(id=self.image_id), # Set labels so we can find the instance if nixops crashes before writing vm_id labels=dict(self._server_labels()), user_data=None if self._ssh_public_key is None else yaml.dump( {"public-keys": [self._ssh_public_key]}), ) self.log_end("") self.public_ipv4 = response.server.public_net.ipv4.ip self.log_start("waiting for SSH...") self.wait_for_up(callback=lambda: self.log_continue(".")) self.log_end("") with self.depl._db: self.vm_id = response.server.id # TODO get state from creation response self.state = MachineState.STARTING self.ssh_keys = ssh_keys self.volume_ids = volume_ids self._detect_hardware() self._update_host_keys() self.filesystems = filesystems
from hcloud.volumes.domain import Volume from mcstatus import MinecraftServer load_dotenv() os.chdir(Path(__file__).parent.absolute()) # Discord config DISCORD_TOKEN = os.getenv("DISCORD_TOKEN") ROLE = int(os.getenv("BOT_PRIVILEDGED_ROLE")) PREFIX = os.getenv("BOT_PREFIX") discord = commands.Bot(PREFIX) # Hetzner config HCLOUD_TOKEN = os.getenv("HCLOUD_TOKEN") SERVER_NAME = os.getenv("SERVER_NAME") SERVER_TYPE = ServerType(name=os.getenv("SERVER_TYPE")) SERVER_IMAGE = Image(name=os.getenv("SERVER_IMAGE")) hcloud = hcl.Client(HCLOUD_TOKEN) def get_volume() -> Volume: return hcloud.volumes.get_by_name(SERVER_NAME) def requires_role(): """Short-hand for commands.has_role(ROLE)""" return commands.has_role(ROLE) @discord.event async def on_command_error(ctx, error: commands.CommandError):