Retire Packaging Deb project repos

This commit is part of a series to retire the Packaging Deb
project. Step 2 is to remove all content from the project
repos, replacing it with a README notification where to find
ongoing work, and how to recover the repo if needed at some
future point (as in
https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project).

Change-Id: I683c8ce852336c719cbbab0bcd25ad4dbd664dff
changes/01/503301/1
Tony Breeds 6 years ago
parent b765ac3814
commit 779c84672b

31
.gitignore vendored

@ -1,31 +0,0 @@
*.pyc
*.sqlite
*.gem
# vim swap files
.*.swp
# services' runtime files
*.log
*.pid
# Vagrant housekeeping file
.vagrant
build
dist
lock
*.egg
.testrepository
.tox
.venv
.idea
.DS_Store
test_run/*
*.egg-info
fuelclient-*.xml
.coverage

@ -1,4 +0,0 @@
[gerrit]
host=review.openstack.org
port=29418
project=openstack/python-fuelclient.git

@ -1,5 +0,0 @@
[DEFAULT]
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_LOG_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./fuelclient/tests/unit} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
test_run_concurrency=echo 1

@ -1,69 +0,0 @@
---
description:
For Fuel team structure and contribution policy, see [1].
This is repository level MAINTAINERS file. All contributions to this
repository must be approved by one or more Core Reviewers [2].
If you are contributing to files (or create new directories) in
root folder of this repository, please contact Core Reviewers for
review and merge requests.
If you are contributing to subfolders of this repository, please
check 'maintainers' section of this file in order to find maintainers
for those specific modules.
It is mandatory to get +1 from one or more maintainers before asking
Core Reviewers for review/merge in order to decrease a load on Core Reviewers [3].
Exceptions are when maintainers are actually cores, or when maintainers
are not available for some reason (e.g. on vacation).
[1] http://specs.openstack.org/openstack/fuel-specs/policy/team-structure.html
[2] https://review.openstack.org/#/admin/groups/551,members
[3] http://lists.openstack.org/pipermail/openstack-dev/2015-August/072406.html
Please keep this file in YAML format in order to allow helper scripts
to read this as a configuration data.
maintainers:
- ./:
- name: Alexander Saprykin
email: asaprykin@mirantis.com
IRC: asaprykin
- name: Bulat Gaifullin
email: bgaifullin@mirantis.com
IRC: bgaifullin
- name: Maciej Kwiek
email: mkwiek@mirantis.com
IRC: mkwiek
- name: Sylwester Brzeczkowski
email: sbrzeczkowski@mirantis.com
IRC: sylwesterB
- specs/:
- name: Mikhail Ivanov
email: mivanov@mirantis.com
IRC: mivanov
- name: Artem Silenkov
email: asilenkov@mirantis.com
IRC: asilenkov
- name: Alexander Tsamutali
email: atsamutali@mirantis.com
IRC: astsmtl
- name: Daniil Trishkin
email: dtrishkin@mirantis.com
IRC: dtrishkin
- name: Ivan Udovichenko
email: iudovichenko@mirantis.com
IRC: tlbr
- name: Igor Yozhikov
email: iyozhikov@mirantis.com
IRC: IgorYozhikov

@ -1 +0,0 @@
include fuelclient/fuel_client.yaml

@ -0,0 +1,14 @@
This project is no longer maintained.
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
For ongoing work on maintaining OpenStack packages in the Debian
distribution, please see the Debian OpenStack packaging team at
https://wiki.debian.org/OpenStack/.
For any further questions, please email
openstack-dev@lists.openstack.org or join #openstack-dev on
Freenode.

@ -1,38 +0,0 @@
========================
Team and repository tags
========================
.. image:: http://governance.openstack.org/badges/python-fuelclient.svg
:target: http://governance.openstack.org/reference/tags/index.html
.. Change things from this point on
python-fuelclient
=================
python-fuelclient provides a CLI tool and a Python API wrapper for interacting
with `Fuel <https://github.com/stackforge/fuel-web>`_.
-----------------
Project resources
-----------------
Project status, bugs, and blueprints are tracked on Launchpad:
https://launchpad.net/fuel
Development documentation is hosted here:
https://docs.fuel-infra.org/fuel-dev
User guide can be found here:
http://docs.mirantis.com
Any additional information can be found on the Fuel's project wiki
https://wiki.openstack.org/wiki/Fuel
Anyone wishing to contribute to python-fuelclient should follow the general
OpenStack process. A good reference for it can be found here:
https://wiki.openstack.org/wiki/How_To_Contribute
http://docs.openstack.org/infra/manual/developers.html

@ -1,90 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# DO NOT PUT ANY IMPORTS HERE BECAUSE THIS FILE IS USED
# DURING THE INSTALLATION.
try:
import pkg_resources
try:
__version__ = pkg_resources.get_distribution(
"python-fuelclient").version
except pkg_resources.DistributionNotFound:
__version__ = ""
except ImportError:
__version__ = ""
def connect(host, port, http_proxy=None, os_username=None, os_password=None,
os_tenant_name=None, debug=False):
"""Creates API connection."""
from fuelclient import client
return client.APIClient(
host, port, http_proxy=http_proxy, os_username=os_username,
os_password=os_password, os_tenant_name=os_tenant_name, debug=debug)
def get_client(resource, version='v1', connection=None):
"""Gets an API client for a resource
python-fuelclient provides access to Fuel's API
through a set of per-resource facades. In order to
get a proper facade it's necessary to specify the name
of the API resource and the version of Fuel's API.
:param resource: Name of the resource to get a facade for.
:type resource: str
Valid values are environment, node and task
:param version: Version of the Fuel's API
:type version: str,
Available: v1. Default: v1.
:param connection: API connection
:type connection: fuelclient.client.APIClient
:return: Facade to the specified resource that wraps
calls to the specified version of the API.
"""
from fuelclient import v1
version_map = {
'v1': {
'cluster-settings': v1.cluster_settings,
'deployment_history': v1.deployment_history,
'deployment-info': v1.deployment_info,
'environment': v1.environment,
'extension': v1.extension,
'fuel-version': v1.fuelversion,
'graph': v1.graph,
'health': v1.health,
'network-configuration': v1.network_configuration,
'network-group': v1.network_group,
'node': v1.node,
'openstack-config': v1.openstack_config,
'plugins': v1.plugins,
'release': v1.release,
'role': v1.role,
'sequence': v1.sequence,
'snapshot': v1.snapshot,
'task': v1.task,
'tag': v1.tag,
'vip': v1.vip
}
}
try:
return version_map[version][resource].get_client(connection)
except KeyError:
msg = 'Cannot load API client for "{r}" in the API version "{v}".'
raise ValueError(msg.format(r=resource, v=version))

@ -1,19 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""fuelclient.cli sub-module contains functionality of
fuelclient command line interface
"""

@ -1,80 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""fuelclient.cli.actions sub-module contains files with action classes
which implement command line interface logic
All action classes must be added to action_tuple to be used by parser
"""
from fuelclient.cli.actions.deploy import DeployChangesAction
from fuelclient.cli.actions.deploy import RedeployChangesAction
from fuelclient.cli.actions.deployment_tasks import DeploymentTasksAction
from fuelclient.cli.actions.environment import EnvironmentAction
from fuelclient.cli.actions.fact import DeploymentAction
from fuelclient.cli.actions.fact import ProvisioningAction
from fuelclient.cli.actions.graph import GraphAction
from fuelclient.cli.actions.token import TokenAction
from fuelclient.cli.actions.health import HealthCheckAction
from fuelclient.cli.actions.interrupt import ResetAction
from fuelclient.cli.actions.interrupt import StopAction
from fuelclient.cli.actions.network import NetworkAction
from fuelclient.cli.actions.network import NetworkTemplateAction
from fuelclient.cli.actions.network_group import NetworkGroupAction
from fuelclient.cli.actions.node import NodeAction
from fuelclient.cli.actions.nodegroup import NodeGroupAction
from fuelclient.cli.actions.notifications import NotificationsAction
from fuelclient.cli.actions.notifications import NotifyAction
from fuelclient.cli.actions.openstack_config import OpenstackConfigAction
from fuelclient.cli.actions.release import ReleaseAction
from fuelclient.cli.actions.role import RoleAction
from fuelclient.cli.actions.settings import SettingsAction
from fuelclient.cli.actions.snapshot import SnapshotAction
from fuelclient.cli.actions.user import UserAction
from fuelclient.cli.actions.plugins import PluginAction
from fuelclient.cli.actions.fuelversion import FuelVersionAction
from fuelclient.cli.actions.vip import VIPAction
actions_tuple = (
DeployChangesAction,
DeploymentAction,
DeploymentTasksAction,
EnvironmentAction,
FuelVersionAction,
GraphAction,
HealthCheckAction,
NetworkAction,
NetworkGroupAction,
NetworkTemplateAction,
NodeAction,
NodeGroupAction,
NotificationsAction,
NotifyAction,
OpenstackConfigAction,
PluginAction,
ProvisioningAction,
RedeployChangesAction,
ReleaseAction,
ResetAction,
RoleAction,
SettingsAction,
SnapshotAction,
StopAction,
TokenAction,
UserAction,
VIPAction,
)
actions = dict(
(action.action_name, action())
for action in actions_tuple
)

@ -1,129 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from functools import partial
from functools import wraps
import os
import six
from fuelclient.cli import error
from fuelclient.cli.formatting import quote_and_join
from fuelclient.cli.serializers import Serializer
from fuelclient.client import DefaultAPIClient
class Action(object):
"""Action class generalizes logic of action execution
method action_func - entry point of parser with parsed arguments
flag_func_map - is tuple of pairs ("flag", self.some_method) where
"flag" is name of argument which causes "some_method" to be called.
None is used as "flag" when method will be called without any flag.
serializer - is Serializer class instance which supposed to be the
only way to read and write to output or file system.
args - tuple of function calls of functions from arguments module,
is a manifest of all arguments used in action, and is used to initialize
argparse subparser of that action.
"""
def __init__(self):
# Mapping of flags to methods
self.flag_func_map = None
self.serializer = Serializer()
def action_func(self, params):
"""Entry point for all actions subclasses
"""
DefaultAPIClient.debug_mode(debug=params.debug)
self.serializer = Serializer.from_params(params)
if self.flag_func_map is not None:
for flag, method in self.flag_func_map:
if flag is None or getattr(params, flag):
method(params)
break
@property
def examples(self):
"""examples property is concatenation of __doc__ strings from
methods in child action classes, and is added as epilog of help
output
"""
methods_with_docs = set(
method
for _, method in self.flag_func_map
)
return "Examples:\n\n" + \
"\n".join(
six.moves.map(
lambda method: (
"\t" + method.__doc__.replace("\n ", "\n")
),
methods_with_docs
)
).format(
action_name=self.action_name
)
def full_path_directory(self, directory, base_name):
full_path = os.path.join(directory, base_name)
if not os.path.exists(full_path):
try:
os.mkdir(full_path)
except OSError as e:
raise error.ActionException(six.text_type(e))
return full_path
def default_directory(self, directory=None):
return os.path.abspath(os.curdir if directory is None else directory)
def wrap(method, args, f):
"""wrap - is second order function, purpose of which is to
generalize argument checking for methods in actions in form
of decorator with arguments.
'check_all' and 'check_any' are partial function of wrap.
"""
@wraps(f)
def wrapped_f(self, params):
if method(getattr(params, _arg) for _arg in args):
return f(self, params)
else:
raise error.ArgumentException(
"{0} required!".format(
quote_and_join(
"--" + arg for arg in args
)
)
)
return wrapped_f
def check_all(*args):
"""check_all - decorator with arguments, which checks that
all arguments are given before running action method, if
not all arguments are given, it raises an ArgumentException.
"""
return partial(wrap, all, args)
def check_any(*args):
"""check_any - decorator with arguments, which checks that
at least one arguments is given before running action method,
if no arguments were given, it raises an ArgumentException.
"""
return partial(wrap, any, args)

@ -1,74 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.objects.environment import Environment
class ChangesAction(Action):
action_name = None
actions_func_map = {}
def __init__(self):
super(ChangesAction, self).__init__()
self.args = (
Args.get_env_arg(required=True),
Args.get_dry_run_deployment_arg(),
)
self.flag_func_map = (
(None, self.deploy_changes),
)
def print_deploy_info(self, deploy_task):
six.print_("Deployment task with id {t} for the environment {e} "
"has been started.".format(t=deploy_task.id,
e=deploy_task.env.id)
)
def deploy_changes(self, params):
"""To apply all changes to some environment:
fuel --env 1 {action_name}
"""
env = Environment(params.env)
deploy_task = getattr(
env, self.actions_func_map[self.action_name])(
dry_run=params.dry_run)
self.serializer.print_to_output(
deploy_task.data,
deploy_task,
print_method=self.print_deploy_info)
class DeployChangesAction(ChangesAction):
"""Deploy changes to environments
"""
action_name = "deploy-changes"
def __init__(self):
super(DeployChangesAction, self).__init__()
self.actions_func_map[self.action_name] = 'deploy_changes'
class RedeployChangesAction(ChangesAction):
"""Redeploy changes to environment which is in the operational state
"""
action_name = "redeploy-changes"
def __init__(self):
super(RedeployChangesAction, self).__init__()
self.actions_func_map[self.action_name] = 'redeploy_changes'

@ -1,108 +0,0 @@
# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.cli.arguments import group
from fuelclient.cli.formatting import format_table
from fuelclient.v1.deployment_history import DeploymentHistoryClient
class DeploymentTasksAction(Action):
"""Show deployment tasks
"""
action_name = "deployment-tasks"
def __init__(self):
super(DeploymentTasksAction, self).__init__()
self.args = [
group(
Args.get_list_arg("List all deployment tasks"),
),
Args.get_single_task_arg(required=True),
Args.get_deployment_node_arg(
"Node ids."
),
Args.get_status_arg(
"Statuses: pending, error, ready, running, skipped"
),
Args.get_tasks_names_arg(
"Show deployment history for specific deployment tasks names "
"and group output by task"
),
Args.get_show_parameters_arg(
"Show deployment tasks parameters"
),
Args.get_include_summary_arg(
"Show deployment tasks summary"
),
]
self.flag_func_map = (
(None, self.list),
)
def list(self, params):
"""To display all deployment tasks for task:
fuel deployment-tasks --task-id 5
To display deployment tasks for some nodes:
fuel deployment-tasks --task-id 5 --node 1,2
To display deployment tasks for some statuses(pending, error,
ready, running):
fuel deployment-tasks --task-id 5 --status pending,running
To display deployment tasks for some statuses(pending, error,
ready, running) on some nodes:
fuel deployment-tasks --task-id 5 --status error --node 1,2
To display certain deployment tasks results only:
fuel deployment-tasks --task-id 5
--task-name task-name1,task-name2
To display tasks parameters use:
fuel deployment-tasks --task-id 5 --show-parameters
"""
client = DeploymentHistoryClient()
tasks_names = getattr(params, 'task-name', None)
show_parameters = getattr(params, 'show-parameters')
statuses = params.status.split(',') if params.status else []
nodes = params.node.split(',') if params.node else []
tasks_names = tasks_names.split(',') if tasks_names else []
include_summary = getattr(params, 'include-summary')
data = client.get_all(
transaction_id=params.task,
nodes=nodes,
statuses=statuses,
tasks_names=tasks_names,
show_parameters=show_parameters,
include_summary=include_summary
)
if show_parameters:
table_keys = client.tasks_records_keys
else:
table_keys = client.history_records_keys
if include_summary:
table_keys += ('summary',)
self.serializer.print_to_output(
data,
format_table(
data,
acceptable_keys=table_keys
)
)

@ -1,228 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import sys
import six
from fuelclient.cli.actions.base import Action
from fuelclient.cli.actions.base import check_all
from fuelclient.cli.actions.base import check_any
import fuelclient.cli.arguments as Args
from fuelclient.cli.arguments import group
from fuelclient.cli.formatting import format_table
from fuelclient.objects.environment import Environment
class EnvironmentAction(Action):
"""Create, list and modify currently existing environments(clusters)
"""
action_name = "environment"
def __init__(self):
super(EnvironmentAction, self).__init__()
self.args = [
Args.get_env_arg(),
group(
Args.get_list_arg(
"List all available environments"
),
Args.get_set_arg(
"Set environment parameters e.g., its name"
),
Args.get_delete_arg(
"Delete environment with a specific id or name"
),
Args.get_create_arg(
"Create a new environment with "
"specific release id and name"
),
),
Args.get_release_arg(
"Release id"
),
Args.get_force_arg(
"Do it anyway"
),
Args.get_name_arg(
"Environment name"
),
Args.get_nst_arg(
"Set network segment type"
),
Args.get_deployment_tasks_arg("Environment tasks configuration"),
Args.get_attributes_arg("Environment attributes"),
group(
Args.get_download_arg(
"Download configuration of specific cluster"),
Args.get_upload_arg(
"Upload configuration to specific cluster")
),
Args.get_dir_arg(
"Select directory to which download release attributes"),
]
self.flag_func_map = (
("deployment-tasks", self.deployment_tasks),
("attributes", self.attributes),
("create", self.create),
("set", self.set),
("delete", self.delete),
(None, self.list)
)
@check_all("name", "release")
def create(self, params):
"""To create an environment with name MyEnv and release id=1 run:
fuel env create --name MyEnv --rel 1
By default, it creates environment setting neutron with VLAN
network segmentation as network provider
To specify other modes add optional arguments:
fuel env create --name MyEnv --rel 1 --net-segment-type vlan
"""
if params.nst == 'gre':
six.print_(
"WARNING: GRE network segmentation type is deprecated "
"since 7.0 release.", file=sys.stderr)
env = Environment.create(
params.name,
params.release,
params.nst,
)
data = env.get_fresh_data()
self.serializer.print_to_output(
data,
u"Environment '{name}' with id={id} was created!"
.format(**data)
)
@check_all("env")
def set(self, params):
"""To change environment name:
fuel --env 1 env set --name NewEnvName
"""
acceptable_params = ('name', )
env = Environment(params.env, params=params)
# forming message for output and data structure for request body
# TODO(aroma): make it less ugly
msg_template = ("Following attributes are changed for "
"the environment: {env_attributes}")
env_attributes = []
update_kwargs = dict()
for param_name in acceptable_params:
attr_value = getattr(params, param_name, None)
if attr_value:
update_kwargs[param_name] = attr_value
env_attributes.append(
''.join([param_name, '=', str(attr_value)])
)
data = env.set(update_kwargs)
env_attributes = ', '.join(env_attributes)
self.serializer.print_to_output(
data,
msg_template.format(env_attributes=env_attributes)
)
@check_all("env")
def delete(self, params):
"""To delete the environment:
fuel --env 1 env --force delete
"""
env = Environment(params.env, params=params)
if env.status == "operational" and not params.force:
self.serializer.print_to_output(env.data,
"Deleting an operational"
"environment is a dangerous "
"operation. Please use --force to "
"bypass this message.")
return
data = env.delete()
self.serializer.print_to_output(
data,
"Environment with id={0} was deleted"
.format(env.id)
)
def list(self, params):
"""Print all available environments:
fuel env
"""
acceptable_keys = ("id", "status", "name", "release_id", )
data = Environment.get_all_data()
if params.env:
data = filter(
lambda x: x[u"id"] == int(params.env),
data
)
self.serializer.print_to_output(
data,
format_table(
data,
acceptable_keys=acceptable_keys
)
)
@check_all("env")
@check_any("download", "upload")
def deployment_tasks(self, params):
"""Modify deployment_tasks for environment:
fuel env --env 1 --deployment-tasks --download
fuel env --env 1 --deployment-tasks --upload
"""
cluster = Environment(params.env)
dir_path = self.full_path_directory(
params.dir, 'cluster_{0}'.format(params.env))
full_path = '{0}/deployment_tasks'.format(dir_path)
if params.download:
tasks = cluster.get_deployment_tasks()
self.serializer.write_to_path(full_path, tasks)
print("Deployment tasks for cluster {0} "
"downloaded into {1}.yaml.".format(cluster.id, full_path))
elif params.upload:
tasks = self.serializer.read_from_file(full_path)
cluster.update_deployment_tasks(tasks)
print("Deployment tasks for cluster {0} "
"uploaded from {1}.yaml".format(cluster.id, full_path))
@check_all("env")
@check_any("download", "upload")
def attributes(self, params):
"""Modify attributes of the environment:
fuel env --env 1 --attributes --download
fuel env --env 1 --attributes --upload
"""
cluster = Environment(params.env)
dir_path = self.full_path_directory(
params.dir, 'cluster_{0}'.format(params.env))
full_path = '{0}/attributes'.format(dir_path)
if params.download:
attributes = cluster.get_attributes()
self.serializer.write_to_path(full_path, attributes)
print("Attributes of cluster {0} "
"downloaded into {1}.yaml.".format(cluster.id, full_path))
elif params.upload:
attributes = self.serializer.read_from_file(full_path)
cluster.update_attributes(attributes, params.force)
print("Attributes of cluster {0} "
"uploaded from {1}.yaml".format(cluster.id, full_path))

@ -1,136 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.cli.arguments import group
from fuelclient.objects.environment import Environment
class FactAction(Action):
action_name = None
def __init__(self):
super(FactAction, self).__init__()
self.args = [
Args.get_env_arg(required=True),
group(
Args.get_delete_arg(
"Delete current {0} data.".format(self.action_name)
),
Args.get_download_arg(
"Download current {0} data.".format(self.action_name)
),
Args.get_upload_arg(
"Upload current {0} data.".format(self.action_name)
),
Args.get_default_arg(
"Download default {0} data.".format(self.action_name)
),
required=True
),
Args.get_dir_arg(
"Directory with {0} data.".format(self.action_name)
),
Args.get_node_arg(
"Node ids."
),
Args.get_not_split_facts_args(),
]
self.flag_func_map = (
("default", self.default),
("upload", self.upload),
("delete", self.delete),
("download", self.download)
)
def default(self, params):
"""To get default {action_name} information for some environment:
fuel --env 1 {action_name} --default
It's possible to get default {action_name} information
just for some nodes:
fuel --env 1 {action_name} --default --node 1,2,3
"""
env = Environment(params.env)
dir_name = env.write_facts_to_dir(
self.action_name,
env.get_default_facts(
self.action_name, nodes=params.node, split=params.split
),
directory=params.dir,
serializer=self.serializer
)
print(
"Default {0} info was downloaded to {1}".format(
self.action_name,
dir_name
)
)
def upload(self, params):
"""To upload {action_name} information for some environment:
fuel --env 1 {action_name} --upload
"""
env = Environment(params.env)
facts = env.read_fact_info(
self.action_name,
directory=params.dir,
serializer=self.serializer
)
env.upload_facts(self.action_name, facts)
print("{0} facts were uploaded.".format(self.action_name))
def delete(self, params):
"""Also {action_name} information can be left or
taken from specific directory:
fuel --env 1 {action_name} --upload \\
--dir path/to/some/directory
"""
env = Environment(params.env)
env.delete_facts(self.action_name)
print("{0} facts deleted.".format(self.action_name))
def download(self, params):
"""To download {action_name} information for some environment:
fuel --env 1 {action_name} --download
"""
env = Environment(params.env)
dir_name = env.write_facts_to_dir(
self.action_name,
env.get_facts(
self.action_name, nodes=params.node, split=params.split
),
directory=params.dir,
serializer=self.serializer
)
print(
"Current {0} info was downloaded to {1}".format(
self.action_name,
dir_name
)
)
class DeploymentAction(FactAction):
"""Show computed deployment facts for orchestrator
"""
action_name = "deployment"
class ProvisioningAction(FactAction):
"""Show computed provisioning facts for orchestrator
"""
action_name = "provisioning"

@ -1,42 +0,0 @@
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import fuelclient.cli.arguments as Args
from fuelclient.cli.actions.base import Action
from fuelclient.objects.fuelversion import FuelVersion
class FuelVersionAction(Action):
"""Show Fuel server's version
"""
action_name = "fuel-version"
def __init__(self):
super(FuelVersionAction, self).__init__()
self.args = [
Args.get_list_arg("Show fuel version"),
]
self.flag_func_map = (
(None, self.version),
)
def version(self, params):
"""To show fuel version data:
fuel fuel-version
"""
version = FuelVersion.get_all_data()
print(self.serializer.serialize(version))

@ -1,163 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import sys
import six
from fuelclient.cli.actions import base
import fuelclient.cli.arguments as Args
from fuelclient.cli import error
from fuelclient.objects import environment
class GraphAction(base.Action):
"""Manipulate deployment graph's representation."""
action_name = 'graph'
task_types = ('skipped', 'group', 'stage')
def __init__(self):
super(GraphAction, self).__init__()
self.args = (
Args.get_env_arg(),
Args.get_render_arg(
"Render graph from DOT to PNG"
),
Args.get_download_arg(
"Download graph of specific cluster"
),
Args.get_dir_arg(
"Select target dir to render graph."
),
Args.group(
Args.get_skip_tasks(),
Args.get_tasks()
),
Args.get_graph_endpoint(),
Args.get_graph_startpoint(),
Args.get_remove_type_arg(self.task_types),
Args.get_parents_arg(),
Args.get_tred_arg("Apply transitive reduction filter for graph."),
)
self.flag_func_map = (
('render', self.render),
('download', self.download),
)
@base.check_all("env")
def download(self, params):
"""Download deployment graph to stdout
fuel graph --env 1 --download
fuel graph --env 1 --download --tasks A B C
fuel graph --env 1 --download --skip X Y --end pre_deployment
fuel graph --env 1 --download --skip X Y --start post_deployment
Specify output:
fuel graph --env 1 --download > output/dir/file.gv
Get parents only for task A:
fuel graph --env 1 --download --parents-for A
"""
env = environment.Environment(params.env)
parents_for = getattr(params, 'parents-for')
used_params = "# params:\n"
for param in ('start', 'end', 'skip', 'tasks', 'parents-for',
'remove'):
used_params += "# - {0}: {1}\n".format(param,
getattr(params, param))
tasks = params.tasks
if not tasks or (params.skip or params.end or params.start):
tasks = env.get_tasks(
skip=params.skip, end=params.end,
start=params.start, include=params.tasks)
dotraph = env.get_deployment_tasks_graph(tasks,
parents_for=parents_for,
remove=params.remove)
sys.stdout.write(six.text_type(used_params))
sys.stdout.write(six.text_type(dotraph))
@base.check_all("render")
def render(self, params):
"""Render graph in PNG format
fuel graph --render graph.gv
fuel graph --render graph.gv --dir ./output/dir/
To apply transitive reduction filter on rendered graph:
fuel graph --render graph.gv --tred
fuel graph --render graph.gv --dir ./output/dir/ --tred
Read graph from stdin
some_process | fuel graph --render -
"""
if params.render == '-':
dot_data = sys.stdin.read()
out_filename = 'graph.gv'
elif not os.path.exists(params.render):
raise error.ArgumentException(
"Input file does not exist"
)
else:
out_filename = os.path.basename(params.render)
with open(params.render, 'r') as f:
dot_data = f.read()
target_dir = self.full_path_directory(
self.default_directory(params.dir),
''
)
target_file = os.path.join(
target_dir,
'{0}.png'.format(out_filename),
)
if not os.access(os.path.dirname(target_file), os.W_OK):
raise error.ActionException(
'Path {0} is not writable'.format(target_file))
render_graph(dot_data, target_file, params.tred)
print('Graph saved in "{0}"'.format(target_file))
def render_graph(input_data, output_path, tred=False):
"""Renders DOT graph using pygraphviz.
:param input_data: DOT graph representation
:param output_path: path to the rendered graph
:param tred: applies transitive reduction of graph
"""
try:
import pygraphviz
except ImportError:
raise error.WrongEnvironmentError(
"This action requires Graphviz installed "
"together with 'pygraphviz' Python library")
graph = pygraphviz.AGraph(string=input_data)
if tred:
graph = graph.tred()
graph.draw(output_path, prog='dot', format='png')

@ -1,105 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import sys
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.cli.error import EnvironmentException
from fuelclient.cli.formatting import format_table
from fuelclient.cli.formatting import print_health_check
from fuelclient.objects.environment import Environment
import six
class HealthCheckAction(Action):
"""Run health check on environment
"""
action_name = "health"
_allowed_statuses = (
'error',
'operational',
'update_error',
)
def __init__(self):
super(HealthCheckAction, self).__init__()
self.args = (
Args.get_env_arg(required=True),
Args.get_list_arg("List all available checks"),
Args.get_force_arg("Forced test run"),
Args.get_check_arg("Run check for some testset."),
Args.get_ostf_username_arg(),
Args.get_ostf_password_arg(),
Args.get_ostf_tenant_name_arg()
)
self.flag_func_map = (
("check", self.check),
(None, self.list)
)
def check(self, params):
"""To run some health checks:
fuel --env 1 health --check smoke,sanity
"""
env = Environment(params.env)
if env.status not in self._allowed_statuses and not params.force:
raise EnvironmentException(
"Environment is not ready to run health check "
"because it is in {0} state. "
"Health check is likely to fail because of "
"this. Use --force flag to proceed anyway.". format(env.status)
)
if env.is_customized and not params.force:
raise EnvironmentException(
"Environment deployment facts were updated. "
"Health check is likely to fail because of "
"that. Use --force flag to proceed anyway."
)
test_sets_to_check = params.check or set(
ts["id"] for ts in env.get_testsets())
ostf_credentials = {}
if params.ostf_tenant_name is not None:
ostf_credentials['tenant'] = params.ostf_tenant_name
if params.ostf_username is not None:
ostf_credentials['username'] = params.ostf_username
if params.ostf_password is not None:
ostf_credentials['password'] = params.ostf_password
if not ostf_credentials:
six.print_("WARNING: ostf credentials are going to be",
"mandatory in the next release.", file=sys.stderr)
env.run_test_sets(test_sets_to_check, ostf_credentials)
tests_state = env.get_state_of_tests()
self.serializer.print_to_output(
tests_state,
env,
print_method=print_health_check
)
def list(self, params):
"""To list all health check test sets:
fuel --env 1 health
or:
fuel --env 1 health --list
"""
env = Environment(params.env)
test_sets = env.get_testsets()
self.serializer.print_to_output(
test_sets,
format_table(test_sets)
)

@ -1,58 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.objects.environment import Environment
class InterruptAction(Action):
def __init__(self):
super(InterruptAction, self).__init__()
self.args = [
Args.get_env_arg(required=True)
]
self.flag_func_map = (
(None, self.interrupt),
)
def interrupt(self, params):
"""To {action_name} some environment:
fuel --env 1 {action_name}
"""
env = Environment(params.env)
intercept_task = getattr(env, self.action_name)()
self.serializer.print_to_output(
intercept_task.data,
"{0} task of environment with id={1} started. "
"To check task status run 'fuel task --tid {2}'.".format(
self.action_name.title(),
params.env,
intercept_task.data["id"]
)
)
class StopAction(InterruptAction):
"""Stop deployment process for specific environment
"""
action_name = "stop"
class ResetAction(InterruptAction):
"""Reset deployed process for specific environment
"""
action_name = "reset"

@ -1,151 +0,0 @@
# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from fuelclient.cli.actions.base import Action
import fuelclient.cli.arguments as Args
from fuelclient.cli.arguments import group
from fuelclient.objects.environment import Environment
class NetworkAction(Action):
"""Show or modify network settings of specific environments
"""
action_name = "network"
def __init__(self):
super(NetworkAction, self).__init__()
self.args = (
Args.get_env_arg(required=True),
Args.get_dir_arg("Directory with network data."),
group(
Args.get_download_arg(
"Download current network configuration."),
Args.get_verify_arg(
"Verify current network configuration."),
Args.get_upload_arg(
"Upload changed network configuration."),
required=True
)
)
self.flag_func_map = (
("upload", self.upload),
("verify", self.verify),
("download", self.download)
)
def upload(self, params):
"""To upload network configuration from some
directory for some environment:
fuel --env 1 network --upload --dir path/to/directory
"""
env = Environment(params.env)
network_data = env.read_network_data(
directory=params.dir,
serializer=self.serializer
)
env.