Exemplo n.º 1
0
    def run(self):
        """
        Create a new node certificate signed by the root and write it out to
        the current directory.

        :raise PathError: When the root certificate and key cannot be found.
        """
        if self["inputpath"] is None:
            self["inputpath"] = os.getcwd()
        if self["outputpath"] is None:
            self["outputpath"] = os.getcwd()

        self["inputpath"] = FilePath(self["inputpath"])
        self["outputpath"] = FilePath(self["outputpath"])

        try:
            try:
                self["name"] = self["name"].decode("utf-8")
                ca = RootCredential.from_path(self["inputpath"])
                uc = UserCredential.initialize(self["outputpath"], ca,
                                               self["name"])
                self._sys_module.stdout.write(
                    u"Created {user}.crt. You can now give it to your "
                    u"API enduser so they can access the control service "
                    u"API.\n".format(user=uc.username).encode("utf-8"))
            except PathError as e:
                raise UsageError(str(e))
            except (UnicodeEncodeError, UnicodeDecodeError):
                raise UsageError(
                    u"Invalid username: Could not be converted to UTF-8")
        except UsageError as e:
            raise SystemExit(u"Error: {error}".format(error=str(e)))
        return succeed(None)
Exemplo n.º 2
0
def get_api(backend, api_args, reactor, cluster_id):
    """
    Get an storage driver which can be used to create an ``IDeployer``.

    :param BackendDescription backend: Backend to use.
    :param PMap api_args: Parameters to pass the API factory.
    :param reactor: The reactor to use.
    :param cluster_id: The cluster's unique ID.

    :return: An object created by one of the factories in ``self.backends``
        using the configuration from ``self.api_args`` and other useful
        state on ``self``.
    """
    if backend.needs_cluster_id:
        api_args = api_args.set("cluster_id", cluster_id)
    if backend.needs_reactor:
        api_args = api_args.set("reactor", reactor)

    for config_key in backend.required_config:
        if config_key not in api_args:
            raise UsageError(
                u"Configuration error: Required key {} is missing.".format(
                    config_key.decode("utf-8")))

    try:
        return backend.api_factory(**api_args)
    except StorageInitializationError as e:
        if e.code == StorageInitializationError.CONFIGURATION_ERROR:
            raise UsageError(u"Configuration error", *e.args)
        else:
            raise
Exemplo n.º 3
0
 def _check_cert_directory(self):
     cert_path = FilePath(self['cert-directory'])
     self['cert-directory'] = cert_path
     if not cert_path.exists():
         raise UsageError("{} does not exist".format(cert_path.path))
     if not cert_path.isdir():
         raise UsageError("{} is not a directory".format(cert_path.path))
def get_client(options):
    cluster = FilePath(options["cluster-yml"])
    if cluster.exists():
        config = yaml.load(cluster.open())
        certificates_path = cluster.parent()
        user = config["users"][0]
        control_service = None  # figure it out based on cluster.yml
    else:
        certificates_path = FilePath(options["certs-path"])
        if options["user"] is None:
            raise UsageError("must specify --user")
        user = options["user"]
        if options["control-service"] is None:
            raise UsageError("must specify --control-service")
        control_service = options["control-service"]

    user_certificate_filename = "%s.crt" % (user, )
    user_key_filename = "%s.key" % (user, )

    return txflocker_get_client(
        certificates_path=certificates_path,
        user_certificate_filename=user_certificate_filename,
        user_key_filename=user_key_filename,
        target_hostname=control_service,
    )
Exemplo n.º 5
0
    def postOptions(self):
        if self['distribution'] is None:
            raise UsageError("Distribution required.")

        if self['config-file'] is not None:
            config_file = FilePath(self['config-file'])
            self['config'] = yaml.safe_load(config_file.getContent())
        else:
            self['config'] = {}

        provider = self['provider'].lower()
        provider_config = self['config'].get(provider, {})

        package_source = PackageSource(
            version=self['flocker-version'],
            branch=self['branch'],
            build_server=self['build-server'],
        )
        try:
            get_runner = getattr(self, "_runner_" + provider.upper())
        except AttributeError:
            raise UsageError(
                "Provider {!r} not supported. Available providers: {}".format(
                    provider, ', '.join(
                        name.lower() for name in self._get_provider_names()
                    )
                )
            )
        else:
            self.runner = get_runner(
                package_source=package_source,
                dataset_backend=self.dataset_backend(),
                provider_config=provider_config,
            )
    def run(self):
        if not self.get("dataset"):
            raise UsageError("must specify --dataset")
        if not self.get("destination"):
            raise UsageError("must specify --destination")
        self.client = get_client(self.parent)
        self.base_url = get_base_url(self.parent)

        d1 = self.client.get(self.base_url + "/state/nodes")
        d1.addCallback(treq.json_content)
        d2 = self.client.get(self.base_url + "/configuration/datasets")
        d2.addCallback(treq.json_content)

        def got_results((nodes, datasets)):
            dataset = filter_datasets(self["dataset"], datasets)
            primary = filter_primary_node(self["destination"], nodes)
            args = {"primary": primary}
            d = self.client.post(
                self.base_url + "/configuration/datasets/%s" % (dataset, ),
                json.dumps(args),
                headers={'Content-Type': ['application/json']})
            d.addCallback(treq.json_content)
            return d

        d = defer.gatherResults([d1, d2])
        d.addCallback(got_results)

        def initiated_move(result):
            print "initiated move of dataset, please check state",
            print "to observe it actually move."
            print

        d.addCallback(initiated_move)
        return d
Exemplo n.º 7
0
    def postOptions(self):
        s = self.parent.getStore()

        didSomething = False

        if self['admin']:
            didSomething = True
            if self['disable']:
                for app in s.query(webadmin.AdminStatsApplication):
                    app.deleteFromStore()
                    break
                else:
                    raise UsageError('Administrator controls already disabled.')
            else:
                installOn(webadmin.AdminStatsApplication(store=s), s)

        if self['developer']:
            didSomething = True
            if self['disable']:
                for app in s.query(webadmin.DeveloperApplication):
                    app.deleteFromStore()
                    break
                else:
                    raise UsageError('Developer controls already disabled.')
            else:
                installOn(webadmin.DeveloperApplication(store=s), s)

        if not didSomething:
            raise UsageError("Specify something or I won't do anything.")
Exemplo n.º 8
0
    def postOptions(self):
        required_options = [
            "stripe-secret-api-key-path",
            "stripe-publishable-api-key-path",
            "subscription-manager",
            "site-logs-path",
            "wormhole-result-path",
        ]
        for option in required_options:
            if self[option] is None:
                raise UsageError("Missing required option --{}".format(option))

        if not self["secure-ports"]:
            raise UsageError(
                u"Use --secure-port at least once to specify an address for "
                u"the website."
            )
        if self["redirect-to-port"] is not None and not self["insecure-ports"]:
            raise UsageError(
                u"Use --insecure-port at least once or there is no server to "
                u"use --redirect-to-port value."
            )

        p = self["site-logs-path"].parent()
        if not p.isdir():
            p.makedirs()
Exemplo n.º 9
0
    def postOptions(self):
        if self['distribution'] is None:
            raise UsageError("Distribution required.")

        if self['config-file'] is not None:
            config_file = FilePath(self['config-file'])
            self['config'] = yaml.safe_load(config_file.getContent())
        else:
            self['config'] = {}

        if self['flocker-version']:
            rpm_version = make_rpm_version(self['flocker-version'])
            os_version = "%s-%s" % (rpm_version.version, rpm_version.release)
            if os_version.endswith('.dirty'):
                os_version = os_version[:-len('.dirty')]
        else:
            os_version = None

        self['package_source'] = PackageSource(
            version=self['flocker-version'],
            os_version=os_version,
            branch=self['branch'],
            build_server=self['build-server'],
        )

        if self['pip']:
            supported = PIP_DISTRIBUTIONS
        else:
            supported = PACKAGED_CLIENT_DISTRIBUTIONS
        if self['distribution'] not in supported:
            raise UsageError(
                "Distribution %r not supported. Available distributions: %s" %
                (self['distribution'], ', '.join(supported)))
 def postOptions(self):
     if self["kubernetes-namespace"] is None:
         raise UsageError("--kubernetes-namespace is required")
     if (self["k8s-context"] is None) == (not self["k8s-service-account"]):
         raise UsageError("Exactly one of --k8s-context or --k8s-service-account is required")
     if self["k8s-service-account"]:
         if self["kubernetes"] is None:
             raise UsageError("--kubernetes is required with --k8s-service-account")
Exemplo n.º 11
0
    def parseArgs(self):
        if self['flocker-version'] is None:
            raise UsageError("`--flocker-version` must be specified.")

        if self['sdist'] is None:
            raise UsageError("`--sdist` must be specified.")

        if self['output-file'] is None:
            raise UsageError("`--output-file` must be specified.")
 def postOptions(self):
     KubernetesClientOptionsMixin.postOptions(self)
     if self["domain"] is None:
         raise UsageError("--domain is required")
     self["domain"] = self["domain"].strip()
     if self["endpoint"] is None:
         raise UsageError("--endpoint is required")
     if self["endpoint"].endswith("/"):
         self["endpoint"] = self["endpoint"][:-1]
Exemplo n.º 13
0
    def postOptions(self):
        if self['distribution'] is None:
            raise UsageError("Distribution required.")

        if self['config-file'] is not None:
            config_file = FilePath(self['config-file'])
            self['config'] = yaml.safe_load(config_file.getContent())
        else:
            self['config'] = {}

        if self['flocker-version']:
            os_version = "%s-%s" % make_rpm_version(self['flocker-version'])
            if os_version.endswith('.dirty'):
                os_version = os_version[:-len('.dirty')]
        else:
            os_version = None

        package_source = PackageSource(
            version=self['flocker-version'],
            os_version=os_version,
            branch=self['branch'],
            build_server=self['build-server'],
        )

        if self['provider'] not in PROVIDERS:
            raise UsageError(
                "Provider %r not supported. Available providers: %s" %
                (self['provider'], ', '.join(PROVIDERS)))

        if self['provider'] in CLOUD_PROVIDERS:
            # Configuration must include credentials etc for cloud providers.
            try:
                provider_config = self['config'][self['provider']]
            except KeyError:
                raise UsageError("Configuration file must include a "
                                 "{!r} config stanza.".format(
                                     self['provider']))

            provisioner = CLOUD_PROVIDERS[self['provider']](**provider_config)

            self.runner = LibcloudRunner(
                config=self['config'],
                top_level=self.top_level,
                distribution=self['distribution'],
                package_source=package_source,
                provisioner=provisioner,
                variants=self['variants'],
            )
        else:
            self.runner = VagrantRunner(
                config=self['config'],
                top_level=self.top_level,
                distribution=self['distribution'],
                package_source=package_source,
                variants=self['variants'],
            )
Exemplo n.º 14
0
    def parseArgs(self, deployment_config, application_config):
        deployment_config = FilePath(deployment_config)
        application_config = FilePath(application_config)

        if not deployment_config.exists():
            raise UsageError('No file exists at {path}'
                             .format(path=deployment_config.path))

        if not application_config.exists():
            raise UsageError('No file exists at {path}'
                             .format(path=application_config.path))

        self["deployment_config"] = deployment_config.getContent()
        self["application_config"] = application_config.getContent()

        try:
            deploy_config_obj = safe_load(self["deployment_config"])
        except YAMLError as e:
            raise UsageError(
                ("Deployment configuration at {path} could not be parsed as "
                 "YAML:\n\n{error}").format(
                    path=deployment_config.path,
                    error=str(e)
                )
            )
        try:
            app_config_obj = safe_load(self["application_config"])
        except YAMLError as e:
            raise UsageError(
                ("Application configuration at {path} could not be parsed as "
                 "YAML:\n\n{error}").format(
                    path=application_config.path,
                    error=str(e)
                )
            )

        try:
            fig_configuration = FigConfiguration(app_config_obj)
            if fig_configuration.is_valid_format():
                applications = fig_configuration.applications()
                self['application_config'] = (
                    applications_to_flocker_yaml(applications)
                )
            else:
                configuration = FlockerConfiguration(app_config_obj)
                if configuration.is_valid_format():
                    applications = configuration.applications()
                else:
                    raise ConfigurationError(
                        "Configuration is not a valid Fig or Flocker format."
                    )
            self['deployment'] = model_from_configuration(
                applications=applications,
                deployment_configuration=deploy_config_obj)
        except ConfigurationError as e:
            raise UsageError(str(e))
Exemplo n.º 15
0
 def volume(self):
     currentVolume = self._directory.child("current_volume.json")
     if currentVolume.exists():
         volume = json.loads(currentVolume.getContent())["current_volume"]
     else:
         raise UsageError("No active volume: use dvol switch to choose one")
     if not self._directory.child(volume).exists():
         raise UsageError("Active volume %s does not exist: "
                          "use dvol switch to choose another" % (volume, ))
     return volume
Exemplo n.º 16
0
 def postOptions(self):
     """
     Verifica las entradas
     """
     try:
         self['port'] = int(self['port'])
     except ValueError:
         raise UsageError("--port argument must be an integer.")
     if self['mail-storage'] is None:
         raise UsageError("Must specify mail-storafe --mail-storage")
Exemplo n.º 17
0
 def postOptions(self):
     if not self['control-node']:
         raise UsageError("Control node address must be provided.")
     if not self['cert-directory']:
         raise UsageError("Certificates directory must be provided.")
     if self['wait'] is not None:
         try:
             self['wait'] = int(self['wait'])
         except ValueError:
             raise UsageError("The wait timeout must be an integer.")
def filter_primary_node(prefix, nodes):
    candidates = []
    for node in nodes:
        if node["uuid"].startswith(prefix):
            candidates.append(node)
    if len(candidates) == 0:
        raise UsageError("no node uuids matching %s" % (prefix, ))
    if len(candidates) > 1:
        raise UsageError("%s is ambiguous node" % (prefix, ))
    return candidates[0]["uuid"].encode("ascii")
def filter_datasets(prefix, datasets):
    candidates = []
    for dataset in datasets:
        if dataset["dataset_id"].startswith(prefix):
            candidates.append(dataset)
    if len(candidates) == 0:
        raise UsageError("no dataset uuids matching %s" % (prefix, ))
    if len(candidates) > 1:
        raise UsageError("%s is ambiguous dataset" % (prefix, ))
    return candidates[0]["dataset_id"].encode("ascii")
Exemplo n.º 20
0
    def parseArgs(self, deployment_config, application_config, current_config,
                  hostname):
        """
        Parse `deployment_config`, `application_config` and `current_config`
        strings as YAML, and into a :class:`Deployment` instance. Assign
        the resulting instance to this `Options` dictionary. Decode a
        supplied hostname as ASCII and assign to a `hostname` key.

        :param bytes deployment_config: The YAML string describing the desired
            deployment configuration.

        :param bytes application_config: The YAML string describing the desired
            application configuration.

        :param bytes current_config: The YAML string describing the current
            cluster configuration.

        :param bytes hostname: The ascii encoded hostname of this node.

        :raises UsageError: If the configuration files cannot be parsed as YAML
            or if the hostname can not be decoded as ASCII.
        """
        try:
            deployment_config = safe_load(deployment_config)
        except YAMLError as e:
            raise UsageError(
                "Deployment config could not be parsed as YAML:\n\n" + str(e))
        try:
            application_config = safe_load(application_config)
        except YAMLError as e:
            raise UsageError(
                "Application config could not be parsed as YAML:\n\n" + str(e))
        try:
            current_config = safe_load(current_config)
        except YAMLError as e:
            raise UsageError(
                "Current config could not be parsed as YAML:\n\n" + str(e))
        try:
            self['hostname'] = hostname.decode('ascii')
        except UnicodeDecodeError:
            raise UsageError(
                "Non-ASCII hostname: {hostname}".format(hostname=hostname))

        try:
            configuration = FlockerConfiguration(application_config)
            parsed_applications = configuration.applications()
            self['deployment'] = model_from_configuration(
                applications=parsed_applications,
                deployment_configuration=deployment_config)
        except ConfigurationError as e:
            raise UsageError(
                'Configuration Error: {error}'.format(error=str(e)))
        # Current configuration is not written by a human, so don't bother
        # with nice error for failure to parse:
        self["current"] = current_from_configuration(current_config)
Exemplo n.º 21
0
        def postOptions(self):
            """
            Check and finalize the value of the arguments.
            """
            if self['config'] is None:
                raise UsageError("Must specify a config file")
            fp = filepath.FilePath(self['config'])
            if not fp.exists():
                raise UsageError("%s doesn't exist." % (fp.path, ))

            self['config'] = fp
Exemplo n.º 22
0
    def postOptions(self):
        if not self['control-node']:
            raise UsageError("Control node address must be provided.")
        if self.get('cert-directory') is None:
            raise UsageError("Certificate directory must be set.")
        if self.get('tag') is None:
            raise UsageError("Tag must be specified.")

        # This is run last as it creates the actual "runner" object
        # based on the provided parameters.
        super(RunOptions, self).postOptions()
Exemplo n.º 23
0
    def __init__(self):
        self.nodes = []

        self.metadata = self.config.get('metadata', {})
        try:
            creator = self.metadata['creator']
        except KeyError:
            raise UsageError("Must specify creator metadata.")

        if not creator.isalnum():
            raise UsageError(
                "Creator must be alphanumeric. Found {!r}".format(creator))
        self.creator = creator
Exemplo n.º 24
0
    def __init__(self):
        self.vagrant_path = self.top_level.descendant([
            'admin',
            'vagrant-acceptance-targets',
            self.distribution,
        ])
        if not self.vagrant_path.exists():
            raise UsageError("Distribution not found: %s." %
                             (self.distribution, ))

        if self.variants:
            raise UsageError("Unsupored varianta: %s." %
                             (', '.join(self.variants), ))
Exemplo n.º 25
0
def validate_tor_options(o):
    use_tor = "tor" in o["listen"].split(",")
    if use_tor or any((o["tor-launch"], o["tor-control-port"])):
        if tor_provider._import_txtorcon() is None:
            raise UsageError(
                "Specifying any Tor options requires the 'txtorcon' module")
    if not use_tor:
        if o["tor-launch"]:
            raise UsageError("--tor-launch requires --listen=tor")
        if o["tor-control-port"]:
            raise UsageError("--tor-control-port= requires --listen=tor")
    if o["tor-launch"] and o["tor-control-port"]:
        raise UsageError(
            "use either --tor-launch or --tor-control-port=, not both")
Exemplo n.º 26
0
    def __init__(self):
        self.vagrant_path = self.top_level.descendant([
            'admin',
            'vagrant-acceptance-targets',
            self.distribution,
        ])
        self.certificates_path = self.top_level.descendant(
            ['vagrant', 'tutorial', 'credentials'])
        if not self.vagrant_path.exists():
            raise UsageError("Distribution not found: %s." %
                             (self.distribution, ))

        if self.variants:
            raise UsageError("Variants unsupported on vagrant.")
Exemplo n.º 27
0
 def deleteBranch(self, branch):
     volume = self.volume()
     if branch == self.getActiveBranch(volume):
         raise UsageError("Cannot delete active branch, use "
                          "'dvol checkout' to switch branches first")
     if branch not in self.allBranches(volume):
         raise UsageError("Branch %r does not exist" % (branch, ))
     if self._userIsSure():
         self.output("Deleting branch %r" % (branch, ))
         volumePath = self._directory.child(volume)
         branchPath = volumePath.child("branches").child(branch)
         branchPath.remove()
     else:
         self.output("Aborting.")
Exemplo n.º 28
0
 def postOptions(self):
     runstep = None
     for step in range(7):
         if self["step{}".format(step + 1)]:
             if runstep is None:
                 runstep = step
                 self["runstep"] = step + 1
             else:
                 raise UsageError("Only one step option allowed")
     else:
         if runstep is None:
             raise UsageError("One step option must be present")
     if not self["uid"]:
         raise UsageError("A uid is required")
Exemplo n.º 29
0
 def postOptions(self):
     """
     Parse integer parameters, open the message file, and make sure all
     required parameters have been specified.
     """
     try:
         self['smtp-port'] = int(self['smtp-port'])
     except ValueError:
         raise UsageError("--smtp-port argument must be an integer.")
     if self['username'] is None:
         raise UsageError(
             "Must specify authentication username with --username")
     if self['password'] is None:
         raise UsageError(
             "Must specify authentication password with --password")
     if self['from-address'] is None:
         raise UsageError("Must specify from address with --from-address")
     if self['to-address'] is None:
         raise UsageError("Must specify from address with --to-address")
     if self['smtp-host'] is None:
         raise UsageError("Must specify smtp host with --smtp-host")
     if self['message'] is None:
         raise UsageError(
             "Must specify a message file to send with --message")
     try:
         self['message'] = file(self['message'])
     except Exception, e:
         raise UsageError(e)
Exemplo n.º 30
0
 def opt_port(self, portstr):
     """
     Specify the port number to listen on.
     """
     try:
         self['port'] = int(portstr)
     except ValueError:
         raise UsageError(
             "Specify an integer between 0 and 65535 as a port number.")
     if self['port'] >= 2**16:
         raise UsageError(
             "Specify an integer between 0 and 65535 as a port number.")
     elif self['port'] < 0:
         raise UsageError(
             "Specify an integer between 0 and 65535 as a port number.")