Beispiel #1
0
 def addWorker(self, args):
     """
         Adds the given worker to the deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if args.size:
         size = args.size
         if args.memory:
             raise InputErrorException('AmbiguousSize')
     elif args.memory:
         memory = args.memory
         size = self._get_size_from_memory(memory)
     else:
         size = None
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.command:
         raise InputErrorException('NoWorkerCommandGiven')
     try:
         self.api.create_worker(
             app_name,
             deployment_name,
             args.command,
             params=args.params,
             size=size)
     except BadRequestError as e:
         if 'size' in e.msgs:
             if args.memory:
                 raise InputErrorException('InvalidMemory')
             if args.size:
                 raise InputErrorException('InvalidSize')
         else:
             raise
     return True
Beispiel #2
0
 def showAddonCreds(self, args):
     """
         Print the creds.json of all Add-ons
     """
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.addon:
         try:
             addons = self.api.read_addons(app_name, deployment_name)
         except:
             raise
         else:
             print_addon_creds(addons)
             return True
     else:
         try:
             addon = self.api.read_addon(
                 app_name,
                 deployment_name,
                 args.addon)
         except GoneError:
             raise InputErrorException('WrongAddon')
         else:
             print_addon_creds([addon])
             return True
Beispiel #3
0
    def removeUser(self, args):
        """
            Remove a user specified by the user name or email address from an application.
        """
        #noinspection PyTupleAssignmentBalance
        app_name, deployment_name = self.parse_app_deployment_name(args.name)  # @UnusedVariable
        if '@' in args.username:
            if deployment_name:
                users = self.api.read_deployment_users(app_name, deployment_name)
            else:
                users = self.api.read_app(app_name)['users']
            try:
                username = [user['username'] for user in users
                            if user['email'] == args.username][0]
            except IndexError:
                raise InputErrorException('RemoveUserGoneError')
        else:
            username = args.username
        try:
            if deployment_name:
                self.api.delete_deployment_user(app_name, deployment_name,
                                                username)

            else:
                self.api.delete_app_user(app_name, username)

        except GoneError:
            raise InputErrorException('RemoveUserGoneError')
        return True
Beispiel #4
0
 def undeploy(self, args):
     """
         Undeploys the deployment, deletes the database and files.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not self.does_app_exist(app_name):
         raise InputErrorException('WrongApplication')
     if not args.force_delete:
             question = raw_input('Do you really want to delete this ' +
                                  'deployment? This will delete everything including files ' +
                                  'and the database. Type "Yes" without the quotes to delete: ')
     else:
         question = 'Yes'
     if question.lower() == 'yes':
         args.force_delete = True
         try:
             self.api.delete_deployment(app_name, deployment_name)
         except GoneError:
             raise InputErrorException('WrongDeployment')
     else:
         print messages['SecurityQuestionDenied']
     return True
Beispiel #5
0
 def showAddon(self, args):
     """
         Shows the details of an addon.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.addon:
         try:
             addons = self.api.read_addons(app_name, deployment_name)
         except:
             raise
         else:
             print_addon_list(addons)
             return True
     else:
         try:
             addon = self.api.read_addon(
                 app_name,
                 deployment_name,
                 args.addon)
         except GoneError:
             raise InputErrorException('WrongAddon')
         else:
             print_addon_details(addon)
             return True
Beispiel #6
0
 def addAlias(self, args):
     """
         Adds the given alias to the deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.alias:
         raise InputErrorException('NoAliasGiven')
     self.api.create_alias(app_name, args.alias, deployment_name)
     return True
Beispiel #7
0
 def activate(self, args):
     """
         Activate a new user using the information from the
         activation email.
     """
     self.api.set_token(None)
     try:
         self.api.update_user(args.user_name[0],
                              activation_code=args.activation_code[0])
     except GoneError:
         raise InputErrorException('WrongUsername')
     except NotImplementedError:
         raise InputErrorException('CommandNotImplemented')
Beispiel #8
0
 def removeCron(self, args):
     """
         Removes an worker form a deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     try:
         self.api.delete_cronjob(app_name, deployment_name, args.job_id)
     except GoneError:
         raise InputErrorException('NoSuchCronJob')
     return True
Beispiel #9
0
 def _get_size_from_memory(self, memory):
     res = re.match(r'(\d+)(.*)', memory.lower())
     if not res:
         raise InputErrorException('InvalidMemory')
     if res.group(2) in ['mb', 'm', '']:
         size = float(res.group(1)) / 128
     elif res.group(2) in ['gb', 'g']:
         size = float(res.group(1)) * 2 ** 10 / 128
     else:
         raise InputErrorException('InvalidMemory')
     final_size = int(math.ceil(size))
     if final_size != size:
         print >> sys.stderr, 'Memory size has to be a multiple of 128MB and has been rounded up to {0}MB.'.format(final_size * 128)
     return final_size
Beispiel #10
0
 def addCron(self, args):
     """
         Adds the given worker to the deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.url:
         raise InputErrorException('NoCronURLGiven')
     self.api.create_cronjob(
         app_name,
         deployment_name,
         args.url)
     return True
Beispiel #11
0
 def updateAddon(self, args):
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     try:
         self.api.update_addon(
             app_name,
             deployment_name,
             args.addon_old,
             args.addon_new)
     except GoneError:
         raise InputErrorException('WrongAddon')
     else:
         return True
Beispiel #12
0
 def removeAddon(self, args):
     """
         Removes an addon form a deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.addon:
         raise InputErrorException('NoAddonGiven')
     try:
         self.api.delete_addon(app_name, deployment_name, args.addon)
     except GoneError:
         raise InputErrorException('WrongAddon')
     return True
Beispiel #13
0
    def setup(self, args):
        user_config = get_user_config(self.settings)
        ssh_key_path = self._get_setup_ssh_key_path(user_config, args)
        if not is_key_valid(ssh_key_path):
            # If given key path is not default and does not exist
            # we raise an error
            if ssh_key_path != get_default_ssh_key_path():
                raise InputErrorException('WrongPublicKey')

            # If given key path was the default one, we create the key
            # pair for the user
            print >> sys.stderr, "Key '{0}' seems to not be a RSA public key or not found!".format(
                ssh_key_path)
            create_new_default_ssh_keys()

        ssh_key_content = readContentOf(ssh_key_path)

        ssh_auth = self._get_setup_ssh_auth(self.settings, user_config, args)

        if args.email:
            set_user_config(self.settings, email=args.email)

        try:
            users = self.api.read_users()
            self.api.create_user_key(users[0]['username'], ssh_key_content)

        except ConflictDuplicateError:
            # Key already added, nothing to do.
            pass

        set_user_config(self.settings,
                        ssh_auth=ssh_auth,
                        ssh_path=ssh_key_path)
Beispiel #14
0
    def create(self, args):
        """
            Create a new user.
        """
        if not self.settings.user_registration_enabled:
            print messages['RegisterDisabled'].format(
                self.settings.user_registration_url)
            return

        self.api.set_token(None)
        if args.name and args.email and args.password:
            name = args.name[0]
            email = args.email[0]
            password = args.password[0]
        else:
            name = raw_input('Username: '******'CommandNotImplemented')

        print messages['UserCreatedNowCheckEmail']
Beispiel #15
0
    def _details(self, app_or_deployment_name):
        app_name, deployment_name = self.parse_app_deployment_name(app_or_deployment_name)
        if deployment_name:
            try:
                deployment = self.api.read_deployment(
                    app_name,
                    deployment_name)

                try:
                    app_users = self.api.read_app_users(app_name)
                except (UnauthorizedError, ForbiddenError, NotImplementedError):
                    # ok since possibly I am not allowed to see users at all
                    pass

                else:
                    deployment['users'] = [
                        dict(au, app=True)
                        for au in app_users
                    ] + deployment['users']

            except GoneError:
                raise InputErrorException('WrongDeployment')
            else:
                return app_name, deployment_name, deployment
        else:
            try:
                app = self.api.read_app(app_name)

                # only get deployment-users if i can see app-users
                if len(app['users']):
                    try:
                        for deployment in app['deployments']:
                            appname, depname = self.parse_app_deployment_name(deployment['name'])

                            depusers = self.api.read_deployment_users(appname, depname)

                            app['users'].extend(
                                dict(du, deployment=depname)
                                for du in depusers
                            )
                    except (NotImplementedError, BadRequestError):  # for old api-servers
                        pass

            except GoneError:
                raise InputErrorException('WrongApplication')
            else:
                return app_name, deployment_name, app
Beispiel #16
0
def readContentOf(filename):
    """
        Read a given file's content into a string
        Returns contents of given file as string, otherwise "None"
    """
    file_content = ''

    if not os.path.isfile(os.path.abspath(filename)):
        raise InputErrorException('FileNotFound')

    try:
        open_file = open(os.path.abspath(filename), 'r')
        file_content = str(open_file.read())
    except IOError:
        raise InputErrorException('FileReadOrWriteFailed')

    return file_content.strip()
Beispiel #17
0
 def addAddon(self, args):
     """
         Adds the given addon to the deployment.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.addon:
         raise InputErrorException('NoAddonGiven')
     options = None
     if args.options:
         options = parse_additional_addon_options(args.options)
     try:
         self.api.create_addon(app_name, deployment_name, args.addon, options)
     except ConflictDuplicateError:
         raise InputErrorException('DuplicateAddon')
     return True
Beispiel #18
0
 def log(self, args):
     """
     Show the log.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     last_time = None
     while True:
         #noinspection PyUnusedLocal
         logEntries = []
         try:
             logEntries = self.api.read_log(
                 app_name,
                 deployment_name,
                 args.type,
                 last_time=last_time)
         except GoneError:
             raise InputErrorException('WrongApplication')
         if len(logEntries) > 0:
             last_time = datetime.fromtimestamp(float(logEntries[-1]["time"]))
             if args.type == 'worker' and args.wrk_id:
                 logEntries = filter(lambda entry:
                                     entry['wrk_id'] == args.wrk_id, logEntries)
             if args.filter:
                 if args.type in ["error", "worker"]:
                     logEntries = filter(
                         lambda entry: re.search(
                             re.compile(args.filter, re.IGNORECASE),
                             entry['message']),
                         logEntries)
                 if args.type == 'access':
                     logEntries = filter(lambda entry:
                                         re.search(
                                         re.compile(args.filter, re.IGNORECASE),
                                         entry['first_request_line'] +
                                         entry['referer'] +
                                         entry['user_agent'] +
                                         entry['remote_host']),
                                         logEntries)
             print_log_entries(logEntries, args.type)
         time.sleep(2)
Beispiel #19
0
def extract_flag_from_variables(variables, flag_names, flag_value):
    flag_found = False

    for flag_name in flag_names:
        if flag_name in variables:
            variables.remove(flag_name)
            flag_found = True

    if flag_value and flag_found:
        raise InputErrorException('DuplicatedFlag')

    return variables, flag_value or flag_found
Beispiel #20
0
    def delete(self, args):
        """
            Delete your user account.
        """
        apps = self.api.read_apps()
        if len(apps) > 0:
            raise InputErrorException('DeleteAppsBeforeUser')

        users = self.api.read_users()
        if not args.force_delete:
            question = raw_input('Do you really want to delete your user? ' +
                                 'Type "Yes" without the quotes to delete: ')
        else:
            question = 'Yes'
        if question.lower() == 'yes':
            self.api.delete_user(users[0]['username'])
            # After we have deleted our user we should also delete
            # the token_file to avoid confusion
            self.api.set_token(None)
        else:
            raise InputErrorException('SecurityQuestionDenied')
Beispiel #21
0
    def deploy(self, args):
        """
            Deploy a distinct version.

            Since we want to make it as easy as possible we first try to update
            the default deployment and start the newest version of that if no
            other arguments were passed at the command line.
        """
        try:
            #noinspection PyTupleAssignmentBalance
            app_name, deployment_name = self.parse_app_deployment_name(args.name)
        except ParseAppDeploymentName:
            raise InputErrorException('InvalidApplicationName')
        if args.size:
            size = args.size
            if args.memory:
                raise InputErrorException('AmbiguousSize')
        elif args.memory:
            memory = args.memory
            size = self._get_size_from_memory(memory)
        else:
            size = None
        try:
            try:
                self.api.update_deployment(
                    app_name,
                    version=args.version,
                    deployment_name=deployment_name,
                    min_boxes=args.containers,
                    max_boxes=size,
                    stack=args.stack)
            except GoneError:
                try:
                    self.api.create_deployment(
                        app_name,
                        deployment_name=deployment_name,
                        stack=args.stack)
                    self.api.update_deployment(
                        app_name,
                        version=args.version,
                        deployment_name=deployment_name,
                        min_boxes=args.containers,
                        max_boxes=size,
                        stack=args.stack)
                except GoneError:
                    raise InputErrorException('WrongApplication')
                except ForbiddenError:
                    raise InputErrorException('NotAllowed')
        except BadRequestError as e:
            if 'max_boxes_over_max_process_limit' in e.msgs:
                if args.memory:
                    raise InputErrorException('InvalidMemory')
                if args.size:
                    raise InputErrorException('InvalidSize')
            else:
                raise
        else:
            return True
Beispiel #22
0
    def _open(self, app_or_deployment_name):
        app_name, deployment_name = self.parse_app_deployment_name(app_or_deployment_name)
        if not deployment_name:
            deployment_name = 'default'

        try:
            deployment = self.api.read_deployment(
                app_name,
                deployment_name)

        except GoneError:
            raise InputErrorException('WrongDeployment')
        else:
            return app_name, deployment_name, deployment
Beispiel #23
0
 def showAlias(self, args):
     """
         Shows the details of an alias.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.alias:
         aliases = self.api.read_aliases(app_name, deployment_name)
         print_alias_list(aliases)
         return True
     else:
         try:
             alias = self.api.read_alias(
                 app_name,
                 args.alias,
                 deployment_name)
         except GoneError:
             raise InputErrorException('WrongAlias')
         else:
             print_alias_details(alias)
             return True
Beispiel #24
0
 def showWorker(self, args):
     """
         Shows the details of an worker.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.wrk_id:
         workers = (self.api.read_worker(app_name, deployment_name, worker['wrk_id']) for worker in self.api.read_workers(app_name, deployment_name))
         print_worker_list(workers)
         return True
     else:
         try:
             worker = self.api.read_worker(
                 app_name,
                 deployment_name,
                 args.wrk_id)
         except GoneError:
             raise InputErrorException('WrongWorker')
         else:
             print_worker_details(worker)
             return True
Beispiel #25
0
 def showCron(self, args):
     """
         Shows the details of an worker.
     """
     #noinspection PyTupleAssignmentBalance
     app_name, deployment_name = self.parse_app_deployment_name(args.name)
     if not deployment_name:
         raise InputErrorException('NoDeployment')
     if not args.job_id:
         cronjobs = self.api.read_cronjobs(app_name, deployment_name)
         print_cronjob_list(cronjobs)
         return True
     else:
         try:
             cronjob = self.api.read_cronjob(
                 app_name,
                 deployment_name,
                 args.job_id)
         except GoneError:
             raise InputErrorException('NoSuchCronJob')
         else:
             print_cronjob_details(cronjob)
             return True
Beispiel #26
0
    def delete(self, args):
        """
            Delete an application. If we wouldn't check the token here it could
            happen that we ask the user for confirmation and then fire the api
            request. If the token wasn't valid this would result in a
            TokenRequiredError being raised and after getting the credentials
            and creating a token this method would be called a second time.

            This would result in asking the user two times if he really wants
            to delete the app which is a rather bad user experience.
        """
        if self.api.check_token():
            #noinspection PyTupleAssignmentBalance
            app_name, deployment_name = self.parse_app_deployment_name(args.name)
            if not self.does_app_exist(app_name):
                raise InputErrorException('WrongApplication')
            if deployment_name:
                raise InputErrorException('DeleteOnlyApplication')
            if not args.force_delete:
                question = raw_input('Do you really want to delete this ' +
                                     'application? Type "Yes" without the quotes to delete: ')
            else:
                question = 'Yes'
            if question.lower() == 'yes':
                try:
                    self.api.delete_app(app_name)
                except ForbiddenError:
                    raise InputErrorException('NotAllowed')
                except BadRequestError:
                    raise InputErrorException('CannotDeleteDeploymentExist')
                except GoneError:
                    raise InputErrorException('WrongApplication')
            else:
                print messages['SecurityQuestionDenied']
        else:
            raise TokenRequiredError
Beispiel #27
0
    def run_cmd(self, args):
        try:
            app_name, deployment_name = self.parse_app_deployment_name(args.name)
        except ParseAppDeploymentName:
            raise InputErrorException('InvalidApplicationName')

        if deployment_name == '':
            raise InputErrorException('NoDeployment')

        user_host = '{app}-{dep}@{host}'.format(app=app_name, dep=deployment_name, host=SSH_FORWARDER)

        # Refresh our token before sending it to the forwarder.
        try:
            self.api.read_deployment(app_name, deployment_name)
        except GoneError:
            raise InputErrorException('WrongApplication')
        env = 'TOKEN={token}'.format(token=self.api.get_token()['token'])
        if len(args.command) > 0:
            command = '{env} {command}'.format(env=env, command=args.command)
        else:
            raise InputErrorException('NoRunCommandGiven')
        sshopts = shlex.split(os.environ.get('CCTRL_SSHOPTS', ''))
        ssh_cmd = ['ssh', '-t'] + sshopts + ['-p', SSH_FORWARDER_PORT, '--', user_host, command]
        subprocess.call(ssh_cmd)
Beispiel #28
0
    def removeKey(self, args):
        """
            Remove one of your public keys specified by key_id.

            listKeys() shows the key_ids.
        """
        users = self.api.read_users()
        if not args.force_delete:
            question = raw_input('Do you really want to remove your key? ' +
                                 'Type "Yes" without the quotes to remove: ')
        else:
            question = 'Yes'
        if question.lower() == 'yes':
            self.api.delete_user_key(users[0]['username'], args.id[0])
        else:
            raise InputErrorException('SecurityQuestionDenied')
Beispiel #29
0
    def addUser(self, args):
        """
            Add a user specified by the e-mail address to an application.
        """
        #noinspection PyTupleAssignmentBalance
        app_name, deployment_name = self.parse_app_deployment_name(args.name)  # @UnusedVariable
        try:
            if deployment_name:
                self.api.create_deployment_user(app_name, deployment_name, args.email, args.role)

            else:
                self.api.create_app_user(app_name, args.email, args.role)

        except ConflictDuplicateError:
            raise InputErrorException('UserBelongsToApp')
        return True
Beispiel #30
0
    def create(self, args):
        """
            Creates a new application.
        """
        try:
            #noinspection PyTupleAssignmentBalance
            app_name, deployment_name = self.parse_app_deployment_name(args.name)
        except ParseAppDeploymentName:
            raise InputErrorException('InvalidApplicationName')

        if args.buildpack:
            # Did the user choose a default app type and provided a buildpack url?
            if not args.type == 'custom':
                raise InputErrorException('NoCustomApp')
            # Did the user provide a valid buildpack URL?
            elif not is_buildpack_url_valid(args.buildpack):
                raise InputErrorException('NoValidBuildpackURL')
        # Did the user provide a buildpack url if app has a custom type?
        elif args.type == 'custom':
            raise InputErrorException('NoBuildpackURL')

        # Did the user provide the repo type as argument?
        if args.repo:
            repo_type = args.repo
            detection_method = None
        else:
            # No, he/she didn't! Then check if current directory is an app and already has a CVS type ...
            (repo_type, detection_method) = CVSType.by_path(os.getcwd())

            if repo_type is None:
                # Hmm, current directory was nothing. Let's check if either 'bzr' or 'git' is installed ...
                (repo_type, detection_method) = CVSType.by_env()

            if repo_type is None:
                # Hmm, also nothing installed! Ok, we give up and set default = GIT and hope for better times ...
                detection_method = 'CreatingAppAsDefaultRepoType'
                repo_type = CVSType.GIT

        try:
            self.api.create_app(app_name, args.type, repo_type, args.buildpack)
            self.api.create_deployment(
                app_name,
                deployment_name=deployment_name)
            if detection_method:
                print messages[detection_method]
        except GoneError:
            raise InputErrorException('WrongApplication')
        except ForbiddenError:
            raise InputErrorException('NotAllowed')
        else:
            return True