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)
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
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, )
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
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.")
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()
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")
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]
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'], )
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))
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
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")
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")
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)
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
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()
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
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), ))
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")
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.")
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.")
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")
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)
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.")