async def add_machine(
            self, spec=None, constraints=None, disks=None, series=None):
        params = client.AddMachineParams()
        if spec:
            if spec.startswith("ssh:"):
                placement, target, private_key_path = spec.split(":")
                user, host = target.split("@")
                sshProvisioner = provisioner.SSHProvisioner(
                    host=host,
                    user=user,
                    private_key_path=private_key_path,
                )
                params = sshProvisioner.provision_machine()
            else:
                placement = parse_placement(spec)
                if placement:
                    params.placement = placement[0]
        params.jobs = ['JobHostUnits']
        if constraints:
            params.constraints = client.Value.from_json(constraints)
        if disks:
            params.disks = [
                client.Constraints.from_json(o) for o in disks]
        if series:
            params.series = series
        client_facade = client.ClientFacade.from_connection(self.connection())
        results = await client_facade.AddMachines([params])
        error = results.machines[0].error
        if error:
            raise ValueError("Error adding machine: %s" % error.message)
        machine_id = results.machines[0].machine
        if spec:
            if spec.startswith("ssh:"):
                await sshProvisioner.install_agent(
                    self.connection(),
                    params.nonce,
                    machine_id,
                )
        log.debug('Added new machine %s', machine_id)
        return await self._wait_for_new('machine', machine_id)